假设我有一个任意深度的 TypeScript 接口,它描述了应用程序的状态,例如:
interface MyState {
foo: boolean;
bar: {
baz: string;
bur: {
pir: string;
par: { pew: boolean }[]
}
}
}
我现在想编写一种类型,允许我约束字符串数组来描述遵守该接口的对象中任意点的有效路径。例如。所有这些都应该是正确的:
myPath: PathType<MyState> = ["foo"];
myPath = ["bar", "baz"];
myPath = ["bar", "bur"];
myPath = ["bar", "bur", "par"];
Array handling would be cool like:
myPath = ["bar", "bur", "par", 1, "pew"];
无效:
myPath = ["baz"];
myPath = ["bar", "pir"];
myPath = ["any", "random", "crap"];
我尝试过这样的方法:
type PathType<State, Key extends keyof State = keyof State> =
State extends object ?
[Key, ...PathType<State[Key], keyof State[Key]>] : never;
但是它们似乎都因递归而失败,只有数组的第一个条目输入正确,然后它接受所有内容。
谢谢@jcalz,您的评论是正确的答案。
我为数组添加了一个谓词函数并稍微修改了它,这现在对我有用:
type PredicateFunction<ArrayType> = (array: ArrayType, index?: number) => boolean;
type PathTuple<T, A extends (PropertyKey | PredicateFunction<any>)[] = []> =
T extends readonly any[] ?
A | PathTuple<T[number], [...A, number | PredicateFunction<T[number]>]> :
T extends object ?
A | PathTuple<T[keyof T], [...A, keyof T]> :
A;