typescript - Cómo establecer los valores de un objeto en función de la propiedad/clave
Estoy aprendiendo Typescript y tratando de entender cómo establecer el tipo de un objeto basado en la clave (literal de plantilla)
Aquí está el ejemplo:
interface Circle {
radius: number;
}
interface Square {
length: number;
}
type TypeName = "circle" | "square";
type ObjectType<T> =
T extends "circle" ? Circle :
T extends "square" ? Square :
never
type Shape = {
[id: `${TypeName}.${string}`]: ObjectType<TypeName>
}
const circle:Shape = {"circle.anythig": {length: 33}} // Square??
// ^^^^^^ how to force the type based on object property key name?
const square:Shape = {"square.anythig": {length: 33}} // Square
Patio de recreo
Respuesta #1
Puedes usar un tipo mapeado con reasignación de claves para asociar un TypeName dado con su ObjectType correspondiente.
type Shape = {
[ID in TypeName as `${ID}.${string}`]: ObjectType<ID>
}
Esto llevará al error deseado si los tipos no coinciden.
const shape: Shape = {
"circle.anything": { length: 33 },
// ^^^^^^ Type '{ length: number; }' is not assignable to type 'Circle'
"square.anything": { length: 33 }
}
Parque infantil
Respuesta #2
Aquí hay otra implementación, por si alguien está interesado:
interface Circle {
radius: number;
}
interface Square {
length: number;
}
type Shapes = {
circle: Circle
square: Square
}
type TypeName = "circle" | "square";
type Shape = {
[ID in keyof Shapes as`${ID}.${string}`]: Shapes[ID]
}
const t:Shape = {"square.foo": {length: 33}}
