基于 TypeScript 中的索引签名推断通用类型

Inferring a generic type based on an index signature in TypeScript

我有一个用于数据分析的小型 TypeScript 库,其中包括我指定 CSV 文件的列标题的名称,然后在我的代码中大量重复使用它们。

我一直在努力改进我的代码以便推断出这些列名,因此我的 IDE 将开始提供它们作为自动完成建议,但我无法使该推断在和我预想的一样。

这是我的问题的一个最小可重现示例:

interface GenericInterface<T extends string> {
    cols: {
        [key in T]: string | number;
    },
}

// I expect T to be inferred as 'NAME' | 'COUNTRY'
const fileInfoA: GenericInterface = {
    cols: {
        NAME: 'A',
        COUNTRY: 'B',
    },
};

TypeScript Playground

正如评论中提到的,在这个例子中,我预计泛型类型 T 会根据 object 的 属性 名称推断为 'NAME' | 'COUNTRY' ] 在我的 cols 属性 中。但是,TypeScript 告诉我“通用类型 'GenericInterface' 需要 1 个类型参数”。

当然,如果我明确提供该字符串联合类型,错误就会消失。但在某些情况下,我正在处理 CSV 文件,我需要知道 200 多个列的名称,我真的不想重复自己,包括每个联合和 object属性。

我觉得我要么遗漏了一些非常明显的东西,要么试图做一些 TypeScript 不支持的事情。但是我无法在 TypeScript 文档中找到任何内容,也无法通过在线其他地方搜索答案找到解决方案。

你们非常亲密。 为了推断 T 你需要创建额外的函数。

interface GenericInterface<T extends string> {
    cols: {
        [key in T]: string | number;
    },
}


const foo = <T extends string>(arg: GenericInterface<T>) => arg

// <"NAME" | "COUNTRY">(arg: GenericInterface<"NAME" | "COUNTRY">)
foo({
    cols: {
        NAME: 'A',
        COUNTRY: 'B',
    },
})

现在,T 被推断为“NAME” | “国家/地区”。

您可以在我的 article

中找到有关函数参数推断的更多信息

Here 你可以找到文档