typescript - Declaración de tipo con corchetes
Acabo de encontrar el siguiente fragmento de código en https://www.typescriptlang.org/docs/handbook/advanced-types.html#type-guards-and-differentiating-types
type FunctionPropertyNames<T> = {
[K in keyof T]: T[K] extends Function ? K : never;
}[keyof T];
type FunctionProperties<T> = Pick<T, FunctionPropertyNames<T>>;
¿Qué significa [keyof T] después de una declaración de tipo y cómo se llama?
Además, [keyof T] parece una pista para el compilador de que las claves en FunctionalPropertyNames son claves de T, pero ¿por qué el compilador no puede inferir esto a partir de [K in keyof T]?
Respuesta #1
Explicación breve: Este uso obtiene todos los tipos de valores de todas las propiedades.
En primer lugar, [] después de un tipo perfora ese tipo accediendo a ese tipo con una clave (o claves)
type A = { foo: string }
type B = A['foo'] // string
En segundo lugar, tienes un tipo mapeado aquí. Eso significa que es un tipo que mapea sobre todas las claves de algún tipo, lo transforma y luego devuelve un nuevo tipo.
Así que primero veamos esta parte por sí sola:
type StripNonMethods<T> = {
[K in keyof T]: T[K] extends Function ? K : never;
}
Sea lo que sea T, esto creará un tipo que para todas las claves de T donde el valor de cada propiedad sea el nombre de la propiedad (si el valor es una función) o never (si no es una función).
Esto transformaría esto:
type T1 = { a(): void, b: number }
en :
type T2 = StripNonMethods<T1> // { a: 'a', b: never }
Pero el resultado deseado aquí es la cadena 'a', porque estamos intentando obtener todos los nombres de propiedades que son funciones. Así que profundizamos en este tipo con sus propias claves, lo que devuelve todos los valores de todas las propiedades como una unión con [keyof T] al final.
Esto ahora devolvería:
type T3 = T2[keyof T2] // 'a' | never
Y porque never nunca puede existir, por definición, se simplifica fuera de la unión y obtienes simplemente:
'a'
Patio de recreo
Respuesta #2
La sintaxis con corchetes se llama tipos de acceso indexado. Se utiliza para obtener el tipo de propiedad de un tipo específico. Por ejemplo:
Digamos que tenemos un tipo llamado CasiRectángulo:
type AlmostRectangle = {
name: string;
a: number;
b: number;
start: Date;
};
Podemos obtener el tipo de una propiedad específica usando la sintaxis de tipos de acceso indexado:
type NameType = AlmostRectangle["name"]; // string
Podemos pasar la unión de nombres de claves a los corchetes para obtener la unión de tipos de propiedades, por ejemplo:
type MultipleTypes = AlmostRectangle["name" | "start"] // string | Date
keyof AlmostRectangle devuelve la unión de los nombres de las propiedades de AlmostRectangle: "name" | "a" | "b" | "start". Podemos usar eso para obtener todos los tipos de propiedades de AlmostRectangle:
type AlmostRectangleProperty = AlmostRectangle[keyof AlmostRectangle] // string | number | Date
