Búsqueda de sitios web

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 de Tipo todos los miembros de la unión que sean asignables a Unió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.

Artículos relacionados