我正在尝试从只读对象创建类型,即
const Actions = {
'user.crud': ['user.create', 'user.read', 'user.update', 'user.delete'],
} as const
type ActionsType = keyof typeof Actions | typeof Actions[keyof typeof Actions][number]
上面的方法很好地工作并将类型ActionsType
设置为字符串文字(“ user.crud”,“ user.create”等)。
但是,Actions
上面的对象非常简单,实际上,我确实需要通过函数来生成动作。当我将上述内容移植到由函数生成时,即
// set up a function to generate all actions for the passed role
function getActions (role: string): Record<string, string[]> {
return {
[`${role}.crud`]: [`${role}.create`, `${role}.read`, `${role}.update`, `${role}.delete`],
}
}
// generate the Actions from a function
const ActionsFromFunction = {
...getActions('user'),
} as const
// set up the Actions from a readonly object with values generated by getActions()
type ActionsFromFunctionType = keyof typeof ActionsFromFunction | typeof ActionsFromFunction[keyof typeof ActionsFromFunction][number]
该类型ActionsFromFunctionType
不再设置为字符串文字。而是将其设置为:string | number
并且依次类型测试失败,因为接受任何字符串。
我整理了上面的演示:
有没有一种方法可以Actions
通过函数生成对象,同时仍将字符串文字保持在类型内?
您的目标只能通过Typescript模板文字类型实现。它们在Typescript 4.0中不受支持,但在4.1版本中可用。
这是使用打字稿4.1的方法
type CrudOperations<ROLE extends string> = [`${ROLE}.create`, `${ROLE}.read`, `${ROLE}.update`, `${ROLE}.delete`];
type GetActionsResult<ROLE extends string> = string extends ROLE // check if we can infer type
? { [k: string]: string[] } // if type is not inferable
: { [K in `${ROLE}.crud`]: CrudOperations<ROLE> };
function getActions<ROLE extends string>(role: ROLE): GetActionsResult<ROLE> {
return {
[`${role}.crud`]: [`${role}.create`, `${role}.read`, `${role}.update`, `${role}.delete`]
} as GetActionsResult<ROLE>;
}
// falls back to { string: string[] } structure
const actions = getActions('admin' as string);
// generate the Actions from a function
const ActionsFromFunction = {
...getActions('user'),
...getActions('orders'),
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句