定义
R extends { [key: string]: any }
不限制由数字或符号作为键的属性,因为这些都是JavaScript对象中可能的键类型,而不仅仅是那些与索引签名匹配的键类型。
例如以下代码类型正确:
type AType = {
[key: string]: any;
}
const aConst: AType = {
"aaa": 1,
2: 2
}
要仅考虑字符串键,您可以使用附加条件类型声明:
type TypedRouter<P extends string> = any
type Test<R> = R extends {
[key: string]: any;
}
? {
[P in keyof R]: P extends string ? TypedRouter<P> : never // ensuring only string keys considered
}
: never;
IIUC,您想要一个映射类型将(某物)的字典重新映射到 TypedRouter 的字典中,但后者需要一个
string
类型。
TypedRouter<P & string>
解决方法有效,但保留了不正确的键(基本上,它仍然重新映射它们,但P & string
产生一个never
类型,TypedRouter可能处理或不处理):
type TypedRouter<P extends string> = P extends never ? "never" : "ok"
const s1 = Symbol(1)
type T = Test<{
// ^? { 0: "never"; [s1]: "never"; str: "ok"; }
0: 0,
[s1]: 1,
str: 2
}>
如果您想在重新映射期间拒绝这些键,只需 产生一个
never
key:
您可以通过生成
来过滤掉键never
您的情况:
type Test2<R> = R extends {
[key: string]: any;
}
? {
[P in keyof R & string]: TypedRouter<P>
}
: never;
type T2 = Test2<{
// ^? { str: "ok"; }
0: 0,
[s1]: 1,
str: 2
}>
这个怎么样?
type TypedRouter<P extends string> = { route: P };
type Test<R> = R extends { [key: string]: any }
? {
[P in keyof R]: TypedRouter<P & string>;
}
: never;
// Example usage
type Example = {
path1: string;
path2: number;
path3: boolean;
};
type Result = Test<Example>;
// Correct usage: Displaying type structure in a comment
// type Result should look like:
// {
// path1: TypedRouter<"path1">;
// path2: TypedRouter<"path2">;
// path3: TypedRouter<"path3">;
// }
console.log("Type Result structured correctly.");