【问题标题】:Typescript Function Generics打字稿函数泛型
【发布时间】:2023-02-22 10:08:32
【问题描述】:

由于 TS 不允许以下语法:

anObject['aKey'] = 'aValue';

我正在创建以下接口并从中继承所有对象:

interface KeyIndexable {
  [key: string]: any;
}

interface ObjectA extends KeyIndexable {
  a: string;
  b: number;
}

但是现在当我尝试创建一个通用函数变量时,如下所示:

let x: <T extends KeyIndexable>(t: T) => void;
x = (a: ObjectA) => console.log('x');

我收到一条错误消息 Type KeyIndexable is missing the following properties from type ObjectA。 那么在这种情况下我该如何解决呢?

【问题讨论】:

    标签: typescript


    【解决方案1】:

    Typescript 不会阻止您通过字符串键访问对象属性:

    let anObject = {};
    anObject['aKey'] = 'aValue';
    

    或者,也许您应该根据需要调整tsconfig

    您的最后一个错误与不同类型的函数声明和实现有关。
    当你写这个时:

    let x: <T extends KeyIndexable>(t: T) => void;
    

    这意味着“x是一个函数,它接受一个扩展的任何类型的参数KeyIndexable什么都不返回”。
    但是你试图分配给x类型的值“接受一个类型参数的函数ObjectA什么都不返回"。如您所见,这些类型是不同的。因此 TS 无法理解如何检查 x 的参数:应该通过 ObjectA 还是像 KeyIndexable 这样的东西。
    所以你的通用中的 extends 是针对这种情况的:

    let x: <T extends KeyIndexable>(t: T) => void;
    x = (a) => console.log('x');
    
    let a: ObjectA = { a: 'a', b: 1 };
    x(a); // ObjectA is accepted here
    

    如果你想动态创建你的函数并且有不同的参数类型,你应该更好地创建一些工厂来返回一个你需要的参数类型的函数

    【讨论】:

    • 谢谢你的解释。 ObjectA extends KeyIndexable 所以它应该满足类型约束?
    • 我已经更新了我的答案以显示 extends 在这种情况下的用途
    猜你喜欢
    • 2023-02-14
    • 1970-01-01
    • 2020-07-08
    • 2015-11-27
    • 2022-11-11
    • 2018-05-02
    • 2021-11-26
    • 2017-12-14
    • 1970-01-01
    相关资源
    最近更新 更多