type resolvejsonmodule multiple keyof typescript types

resolvejsonmodule - typescript multiple types



¿Hay un `valueof` similar a` keyof` en TypeScript? (2)

Quiero poder asignar una propiedad de objeto a un valor dado una clave y un valor como entradas y aún así poder determinar el tipo del valor. Es un poco difícil de explicar, por lo que este código debería revelar el problema:

type JWT = { id: string, token: string, expire: Date }; const obj: JWT = { id: ''abc123'', token: ''tk01'', expire: new Date(2018, 2, 14) }; function print(key: keyof JWT) { switch (key) { case ''id'': case ''token'': console.log(obj[key].toUpperCase()); break; case ''expire'': console.log(obj[key].toISOString()); break; } } function onChange(key: keyof JWT, value: any) { switch (key) { case ''id'': case ''token'': obj[key] = value + '' (assigned)''; break; case ''expire'': obj[key] = value; break; } } print(''id''); print(''expire''); onChange(''id'', ''def456''); onChange(''expire'', new Date(2018, 3, 14)); print(''id''); print(''expire''); onChange(''expire'', 1337); // should fail here at compile time print(''expire''); // actually fails here at run time

Intenté cambiar value: any a value: valueof JWT pero eso no funcionó.

Idealmente, onChange(''expire'', 1337) fallaría porque 1337 no es un tipo de fecha.

¿Cómo puedo cambiar el value: any para que sea el valor de la clave dada?


ACTUALIZACIÓN: Parece que el título de la pregunta atrae a las personas que buscan una unión de todos los tipos de valores de propiedad posibles, de forma análoga a la forma en que keyof le brinda la unión de todos los tipos de clave de propiedad posibles. Ayudemos a esas personas primero. Puede hacer un ValueOf análogo a keyof , utilizando tipos de búsqueda con keyof T como la clave, de esta manera:

type ValueOf<T> = T[keyof T];

que te da

type Foo = { a: string, b: number }; type ValueOfFoo = ValueOf<Foo>; // string | number

Para la pregunta que se indica, puede usar claves individuales, más estrechas que la keyof T , para extraer solo el tipo de valor que le interesa:

type sameAsString = Foo[''a'']; // lookup a in Foo type sameAsNumber = Foo[''b'']; // lookup b in Foo

Para asegurarse de que el par clave / valor "coincida" correctamente en una función, debe usar generics y tipos de búsqueda, como este:

declare function onChange<K extends keyof JWT>(key: K, value: JWT[K]): void; onChange(''id'', ''def456''); // okay onChange(''expire'', new Date(2018, 3, 14)); // okay onChange(''expire'', 1337); // error. 1337 not assignable to Date

La idea es que el parámetro key permite al compilador inferir el parámetro K genérico. Luego requiere que el value coincida con JWT[K] , el tipo de búsqueda que necesita.

Espero que ayude; ¡buena suerte!


Si alguien todavía busca la implementación de valueof para algún propósito, este es uno que se me ocurrió:

type valueof<T> = T[keyof T]

Uso:

type actions = { a: { type: ''Reset'' data: number } b: { type: ''Apply'' data: string } } type actionValues = valueof<actions>

Funciona como se espera :) Devuelve una unión de todos los tipos posibles