Estoy trabajando en un escenario de manejo de una propiedad de tipo array con acceso indexed . Traté de encapsular el problema en su forma más simple aquí.
type User = { readonly name: string; readonly roles: ReadonlyArray<string>; } const buildActions = <T extends User>(u: T) => { // Implementation return {login: (role: T['roles'][number]) => { console.log(u, role); }} } const actions = buildActions({name: 'user', roles: ['admin', 'client']} as const); actions.login('client'); Así que el código anterior funciona bien. Pero en mi escenario, los roles de propiedad son opcionales.
type User = { readonly name: string; readonly roles?: ReadonlyArray<string>; }En el caso anterior obtenemos un error
El tipo 'número' no se puede usar para indexar el tipo 'T["roles"]'
Traté de usar el tipo condicional para manejar el escenario, pero no funcionó.
const buildActions = <T extends User>(u: T) => { // Implementation return {login: (role: T['roles'] extends never ? never : T['roles'][number]) => { console.log(u, role); }} }Definitivamente no es la forma correcta de manejar tal escenario, pero cubre muy bien el caso de uso.
¿Alguna idea de cómo superar este escenario de tipeo?
Gracias
El uso de los tipos condicionales resolvió el problema.
type User = { readonly name: string; readonly roles?: ReadonlyArray<string>; } const buildActions = <T extends User>(u: T) => { // Implementation return {login: (role: T['roles'] extends string[] ? T['roles'][number] : never) => { console.log(u, role); }} } const actions = buildActions({name: 'user', roles: ['admin', 'client']} as const); actions.login('client'); Lo intenté antes, pero parece que hay problemas de precedencia con la palabra clave TS extends . Considerando que T['roles'] como tipo string[] | undefined El siguiente código a continuación funciona bien:
T['roles'] extends string[] ? T['roles'][number] : neverPero si invertimos la condición falla.
T['roles'] extends undefined ? never : T['roles'][number] Por lo tanto, nunca use tipos condicionales con una afirmación undefined .