【问题标题】:How to define a generic in Typescript that forces an index signature如何在 Typescript 中定义一个强制索引签名的泛型
【发布时间】:2019-09-12 03:58:25
【问题描述】:

在 Typescript 中,要为对象提供索引签名,您可以根据需要以两种方式之一定义它。假设我有一个Indexable 接口和一个EmployeeDir 类型。

type EmployeeType = "contractor" | "permanent";

type EmployeeDir = {
    [key in EmployeeType]: any
}

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

我知道我可以使用接受这两个值中的任何一个的泛型,如下所示:

function limited<T extends EmployeeDir | Indexable>(val: T): T {
    return val;
}

但是我如何强制给定类型具有任何类型的索引签名?我不在乎索引签名是什么,我只想确保它一个。我该怎么办?

// What can I put here to allow any object type at all as
// long has it has a signature definition?
function anything<T /* extends ...*/>(val: T): T {
    return val;
}

我可能正在寻找错误的东西,因为我的所有结果都一直导致“对象没有索引签名”错误,这不是我想要的。

【问题讨论】:

  • 看来你应该能够扩展Indexable,不是吗? EmployeeType(和任何其他有效索引)将是 [key: string] 的子集,因为 JS 要求对象键是字符串。
  • EmployeeDir 没有index signature;这是一个mapped type,计算结果为{ contractor: any; permanent: any; }。映射类型不是索引签名(即使语法看起来很相似),所以我不确定您要的是什么。
  • 感谢@jcalz,这实际上帮助我澄清了事情,我现在可以查看keyof。 @ChrisHeald,[key: number] 不是 TS 中的有效索引方法吗?如何指定允许字符串或数字索引?
  • 等等,如果是这样的话,我可以做{[key: string]: any} | {[key: number]: any},这将涵盖唯一可能的索引签名,因为我了解到映射类型没有它们。谢谢两位的帮助!

标签: typescript


【解决方案1】:

感谢jcalz 的澄清。在我的示例中,EmployeeDir 没有索引签名;这是一个mapped type,其计算结果为:

interface EmployeeDir {
    contractor: any;
    permanent: any;
}

仅有的两个可能的索引签名是{[key: string]: any}{[key: number]: any}。这会让我有一些类似的东西:

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

interface NumberIndexable {
    [key: number]: any;
}

function anything<T extends NumberIndexable | StringIndexable>(val: T): T {
    let key: keyof T;

    for (key in val) {
        let value = val[key];
    }

    return val;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-14
    • 2021-12-30
    • 2015-11-05
    • 2022-10-12
    • 2016-06-18
    • 2019-01-23
    相关资源
    最近更新 更多