[英]Define a nested Record type that narrows as you traverse
我的系統具有定義為字符串 [] 的權限,如下所示
const stringVals = [
'create:user',
'update:user',
'delete:user',
'create:document',
'update:document',
'delete:document',
'delete:workflow',
'run:workflow',
] as const
我有以下類型
type StringVals = typeof stringVals[number]
type PermissionVerb<T extends string> = T extends `${infer Action}:${string}` ? Action : never
type PermissionKey<T extends string, V extends PermissionVerb<T>> = T extends `${V}:${infer Key}` ? Key : never
這對諸如此類的事情非常有用
type Verbs = PermissionVerbs<StringVals> // 'create' | 'update' | 'delete' | 'run'
type CreateKeys = PermissionKey<StringVals, 'create'> // 'user' | 'document'
type RunKeys = PermissionKey<StringVals, 'run'> // 'workflow'
我希望創建一個看起來像這樣的單一權限對象
{
create: {
user: true,
document: true
},
update: {
user: true,
document: true
},
delete: {
user: true,
document: true,
workflow: true,
},
run: {
workflow: true,
}
}
它正在為我正在努力解決的這個對象定義正確的類型。
type PermissionsObject<T extends string> = Record<PermissionVerb<T>, Record<PermissionKey<T, PermissionVerb<T>>, boolean>>
function createPermissionsObject<T extends string>(permissions: Readonly<T[]>): PermissionsObject<T> {
throw 'not implemented'
}
問題是第一個記錄不會縮小內部記錄。 所以run
的外部對象鍵返回所有內容,而不僅僅是我想要的workflow
。
const permissions = createPermissionsObject(stringVals)
permissions.run.user // expect error
我們必須使用映射類型,以便每個鍵K
都可以用來計算其對應的類型。
type PermissionsObject<T extends string> = {
[K in PermissionVerb<T>]:
Extract<T, `${K}${string}`> extends `${string}:${infer Key}`
? Record<Key, boolean>
: never
}
K
可以與Extract
一起使用以從T
獲取完整路徑,其中K
是Action
。 我們現在可以從這個結果中infer
出Key
並在Record<Key, boolean>
中使用它。
const permissions = createPermissionsObject(stringVals)
permissions.run.workflow
permissions.create.user
permissions.run.user
// ^^^^ Property 'user' does not exist on type
// 'Record<"workflow", boolean>'
獎金:
幾個字符更短但結果相同。
type PermissionsObject<T extends string> = {
[K in T as PermissionVerb<K>]:
[K] extends [`${string}:${infer Key}`]
? Record<Key, boolean>
: never
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.