typescript - 使用 TS 条件类型缩小数值属性

标签 typescript

我正在尝试使用条件类型并尝试对此进行验证。有趣的是, 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/

相关文章:

node.js - Typescript - tsc 编译器破坏了我的代码

typescript - TypeORM:如何使用查询运行器部分更新给定的实体?

javascript - 如何自动调用System或AMD模块?

typescript - 如何将 RxJs 6 与 TypeScript 和 WebPack 一起使用

reactjs - 在遵循 React、Express 和 Typescript 教程时尝试添加 & { session : Express. Session } 以键入 MyContext 时出现 "No exported member"错误

typescript - 如何正确键入对象方法的包装函数?

javascript - 类型错误 : Cannot read property 'http' of undefined

TypeScript:从 JSON 反序列化到有区别的联合

javascript - 为什么 import 关键字有用?

javascript - 在 JavaScript 中访问 Office UI Fabric 主题颜色