【问题标题】:Why simple interface can't assign to Record<string, any>?为什么简单的接口不能分配给 Record<string, any>?
【发布时间】:2021-10-05 17:53:43
【问题描述】:

尝试为 CSV 文件创建通用类型。

export interface Row {
    id: number;
    name: string;
}

export type CsvFile<T = Record<string, any>> = {
    data: T[];
    headers: Array<keyof T>;
};

function some(f: CsvFile) {
...
}
let test: CsvFile<Row>;
some(test);

 error TS2345: Argument of type 'CsvFile<Row>' is not assignable to parameter of type 'CsvFile<Record<string, any>>'.
  Type 'Record<string, any>' is missing the following properties from type 'Row': id, name

在我读到的一些答案中,我可以使用类型代替接口,但这无济于事,错误保持不变。即使有索引签名:

export type Row = {
  id: number;
  name: string;
  [index: string]: any;
}

没有任何变化:(

【问题讨论】:

  • 应该是 T extends Record 而不是 T=Records
  • 这是 TypeScript 的设计限制;见microsoft/TypeScript#43608。可能有一些变通方法,可能是通过强制进行结构比较。在这里,like this。 @Crusader 这对你有用吗?如果是这样,我可以写一个答案;如果不是,请详细说明失败的用例。

标签: typescript type-safety


【解决方案1】:

这是一个工作示例 只需将T =Record&lt;string, any&gt;&gt; 替换为T extends Record&lt;string, any&gt;&gt;

export interface Row {
    id: number;
    name: string;
}

export type CsvFile<T extends  Record<string, any>> = {
    data: T[];
    headers: Array<keyof T>;
};

function some(f: CsvFile<Row>) {
console.log("jlkl")
}
let test: CsvFile<Row>;
some(test);

【讨论】:

  • 我认为some 函数的重点是获取任何CsvFile,因此我建议改为function some&lt;T&gt;(f: CsvFile&lt;T&gt;) {
猜你喜欢
  • 2021-04-24
  • 2022-06-11
  • 2022-09-24
  • 2023-01-18
  • 2021-03-06
  • 2021-08-13
  • 2022-01-20
  • 2021-07-03
  • 2021-03-13
相关资源
最近更新 更多