typescript - Por qué keyof T no funciona en un objeto genérico
Me gustaría tener una función con un tipo genérico T que debe ser un objeto y debe tener al menos una propiedad llamada code de tipo string, y luego usar keyof T para obtener todas las claves del objeto.
¿Por qué esto es inválido?
function TableView<T extends { code: string }>() {
return forwardRef<HTMLDivElement, { data: T[], columns: Columns<keyof T> }>(
(props, ref) => {
Error :
TS2344: Type 'keyof T' does not satisfy the constraint 'string'.
Type 'string | number | symbol' is not assignable to type 'string'.
Type 'number' is not assignable to type 'string'.
dónde :
export interface Column<T extends string> {
field: T;
label: string;
align?: "left" | "center" | "right"
format?: "number" | "integer" | "percent" | "timestamp" | "text"
backgroundColor?: (row: any) => string
}
type Columns<T extends string> = Column<T>[]
export default Columns
Respuesta #1
Teóricamente, T puede tener no solo claves string (number | symbol también están permitidos). Si quieres seleccionar solo las claves string, puedes usar la utilidad Extract:
const e = Symbol();
type Foo = {
a: string; // String-like name
5: string; // Number-like name
[e]: string; // Symbol-like name
};
type K1 = keyof Foo; // "a" | 5 | typeof e
type K2 = Extract<keyof Foo, string>; // "a"
Parque infantil
Extract<Tipo, Unión>Construye un tipo extrayendo deTipotodos los miembros de la unión que sean asignables aUnión
Otra opción sugerida por @kaya3 es usar la intersección string & keyof T.
Respuesta #2
Simplemente cambia extends string a extends any. Te dará el mismo resultado que estás buscando. El problema es que keyof puede ser tipificado como algo más que solo una cadena.
