Me gustaría declarar una matriz de elementos de tipo obligatorio y poder derivar un tipo de unión a partir de ella. Este patrón funciona si no proporciona explícitamente un tipo a los elementos de la matriz. No estoy seguro de cómo explicarlo mejor, así que aquí hay un ejemplo:
EJEMPLO 1
type Pair = {
key: string;
value: number;
};
const pairs: ReadonlyArray<Pair> = [
{ key: 'foo', value: 1 },
{ key: 'bar', value: 2 },
] as const;
type Keys = typeof pairs[number]['key']
EJEMPLO 2
type Data = {
name: string;
age: number;
};
const DataRecord: Record<string, Data> = {
foo: { name: 'Mark', age: 35 },
bar: { name: 'Jeff', age: 56 },
} as const;
type Keys = keyof typeof DataRecord;
Aquí hay un ejemplo de derivación de las claves cuando se usa as const
. Quiero este mismo comportamiento pero con la matriz que se escribe explícitamente.
const pairs = [
{ key: 'foo', value: 1 },
{ key: 'bar', value: 2 },
] as const;
type Keys = typeof pairs[number]['key']; // "foo" | "bar"
valor deseado de claves: "foo"|"bar"
valor real de las claves: string
key
atributo delPair
tipo el tipo que desee, entonces debería funcionar como lo ha escrito.possibleKeys = ['foo', 'bar'] as const; type Keys = typeof possibleKeys[number]; type Pair = { key: Keys, value: number };
pero aún necesita enumerar explícitamente las posibles claves.Respuestas:
Para una variable, puede dejar que el compilador deduzca el tipo de la inicialización o escribirlo explícitamente. Si lo escribe explícitamente, como lo ha hecho, entonces el valor de inicialización se compara con la anotación, pero el tipo real del inicializador no afecta el tipo de la variable (por lo que pierde la información de tipo que desea). Si deja que el compilador lo infiera, ya no es posible restringir el tipo para que se ajuste a una interfaz específica (como parece querer)
La solución para esto es usar una función genérica para restringir el valor e inferir su tipo real:
Enlace de juegos
Nota: Para el caso de la matriz, necesitamos armar un poco el compilador para inferir los tipos literales de cadena para
key
, por lo tanto, el conjunto& Array<{key: V}>
, dondeV
se extiende un parámetro de tipostring
fuente
Los enfoques habituales son:
pairs
omitiendo el tipo explícitoReadonlyArray<Pair>
(vea la respuesta )key
enPair
el tipo"foo"|"bar"
Si no desea hacer esto, entonces la única forma de inferir sus claves y restringir el tipo de
pairs
es utilizar una función auxiliar. ElPair
tipo también se hará genérico para guardar loskey
tipos literales de cadena dados . Puede usar un IIFE para hacer la asignación compacta:Patio de recreo
fuente