我实现了类型推断
TailProp
,用于获取输入的属性。以下是一些示例:
TailProp<'foo'> // foo
TailProp<'foo.bar'> // bar
TailProp<'foo.bar...baz'> // baz
TailProp<''> // never
TailProp<'...'> // never
由此看来,
TailProp<?>
只会产生never
或string
。我可以假设它相当于:
TailProp<...> = string | never
这是我的实现:
type StrLen<T extends string, R extends Array<string> = []> = T extends `${infer C}${infer P}`
? StrLen<P, [...R, C]>
: R['length']
type StrSplit<T extends string, S extends string, R extends Array<string> = []> = T extends `${infer X}${S}${infer Y}`
? StrSplit<Y, S, StrLen<X> extends 0 ? R : [...R, X]>
: StrLen<T> extends 0
? R
: [...R, T]
type Last<T extends Array<string>> = T extends [...infer _, infer Y] ? Y : never
type TailProp<T extends string> = Last<StrSplit<T, '.'>>
我在使用时遇到问题:
type PickSource<T extends Array<string>, S extends Record<string, any> = {}> = {
[K in T[number] as TailProp<K>]: K extends keyof S ? S[K] : unknown
}
TailProp<K>
会导致以下错误:
Type 'Last<StrSplit<K, ".", []>>' is not assignable to type 'string | number | symbol'.
Type 'Last<StrSplit<T[number], ".", []>>' is not assignable to type 'string | number | symbol'.
Type 'unknown' is not assignable to type 'string | number | symbol'.ts(2322)
我有一些问题:
type MyOmit<T extends Record<string, any>, K extends keyof T> = {
[P in keyof T as P extends K ? never : P]: T[P] // Use never here
}
这表示允许在
never
之后使用 as
。根据前面的假设,代码 [K in T[number] as TailProp<K>]
应该是有效的。
...
[K in T[number] as TailProp<"foo">]: ...
...
这不会产生错误,并且在这种情况下
K
只会是字符串。那么为什么TailProp<K>
不起作用呢?是不是因为类型推断太复杂了?