gpt4 book ai didi

typescript 将缺少的字段添加到应该具有它们的类型

转载 作者:行者123 更新时间:2023-12-04 10:46:45 24 4
gpt4 key购买 nike

我正在尝试为我的数据库代码创建一个辅助函数。数据库中的每个表都有一些公共(public)字段(pk、创建日期等),这些字段被实现为其他表的接口(interface)扩展的公共(public)接口(interface)。我想创建一个函数,自动将这些公共(public)属性添加到对象并返回新对象,但是 typescript 以我无法理解的方式提示子类型分配......

Type '{ id: string; } & Pick<T, Exclude<keyof T, "id">>' is not assignable to type 'T'.
'{ id: string; } & Pick<T, Exclude<keyof T, "id">>' is assignable to the constraint of type
'T', but 'T' could be instantiated with a different subtype of constraint 'Common'

我在 TS 操场上做了一个最小的代码示例来重现它。对于给定类型,T 扩展了 Common 基接口(interface),我想接受一个包含 T 的所有必需字段的对象,除了 Common 中的那些,然后返回带有添加字段的对象。
interface Common {
id: string;
}

interface Table extends Common {
data: string;
}

function makeDbEntry<T extends Common>(initial: Omit<T, 'id'>): T {
const common: Common = {
id: 'random string',
};
const ret: T = {
...common,
...initial,
};
return ret;
}

Playground Link

据我所知,似乎没有任何方法可以在不明确列出其字段的情况下从 T 中删除字段(不能执行“T 减去 Common”)...

最佳答案

如果条件类型包含类型参数,则无法完全解析它们。这意味着,至少对于这个用例,Omit<T, 'id'>基本上是不透明的,TS看不到这个类型是什么,它只是一个与T不同的类型.
当您进行展开操作时,TS 正确理解这将在 common 和 Omit<T, 'id'> 之间产生交集。 ({ id: string; } & Omit<T, 'id'>)。但是自从Omit正如我所说的不透明,无法对这种类型进行进一步的简化。即使对人类来说,这很容易解析为 T , typescript 不知道如何简化这种类型。
如果替换 T有了具体的类型,那么 ts 就可以很容易理解了,比如 { id: string; } & Omit<Table, 'id'>Table 相同,所以这有效:

function makeDbEntryForTable(initial: Omit<Table, 'id'>): Table {
const common: Common = {
id: 'random string',
};
const ret: Table = {
...common,
...initial,
};
return ret;
}
对于通用版本,最好的选择是使用类型断言,因为在大多数情况下,开发人员比编译器有更好的理解:
function makeDbEntry<T extends Common>(initial: Omit<T, 'id'>): T {
const common: Common = {
id: 'random string',
};
const ret: T = {
...common,
...initial,
} as T;
return ret;
}

Playground Link

关于 typescript 将缺少的字段添加到应该具有它们的类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59669867/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com