我正在尝试使用条件类型并尝试对此进行验证。有趣的是, test() 函数确实验证我是否传递“val”作为参数,如果我传递“name”则失败......这是预期的行为。然而,Typescript 显然不认为 o[p] 可以被认为是一个数字,并抛出这个:
运算符“+=”不能应用于类型“number”和“T[{ [K in keyof T]: T[K] extends number ? K:从不; }[T 键]]'。
我是否误解了用法?我认为“从不”会禁止任何不是明确数字的参数...
class Test {
public static SumParam<T>
(t: T[], p:{ [K in keyof T]: T[K] extends number ? K : never }[keyof T]): number {
let n:number = 0;
for (let o of t) {
n += o[p]; //Operator '+=' cannot be applied to types 'number' and 'T[{ [K in keyof T]: T[K] extends number ? K : never; }[keyof T]]'.
}
return (n);
}
public test(): void {
Test.SumParam(
[{ name: "alice", val: 3 },
{ name: "bob", val: 4 }],
"val"); //validates
Test.SumParam(
[{ name: "alice", val: 3 },
{ name: "bob", val: 4 }],
"name"); //Argument of type '"name"' is not assignable to parameter of type '"val"'.
}
}
编译器缩小范围并识别“val”是扩展数字的唯一可枚举属性这一事实...这是否意味着条件语法正在起作用...?
最佳答案
Typescript 将无法遵循其中仍包含未解析的类型参数的条件类型。因此,它无法知道 o[p]
是 number 类型。
如果您不介意数组中的项目出现错误,您可以以允许 typescript 知道o[p]
是数字的方式键入函数:
class Test {
public static SumParam<T extends Record<K, number>, K extends keyof T>
(t: T[], p: K): number {
let n:number = 0;
if (!t) return (n);
for (let o of t) {
n += o[p]; //ok.
}
return (n);
}
public test(): void {
Test.SumParam(
[{ name: "alice", val: 3 },
{ name: "bob", val: 4 }],
"val"); //ok, no error here
Test.SumParam(
[{ name: "alice", val: 3 }, // Type 'string' is not assignable to type 'number'.
{ name: "bob", val: 4 }], // Type 'string' is not assignable to type 'number'.
"name");
}
}
关于typescript - 使用 TS 条件类型缩小数值属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56119710/