gpt4 book ai didi

typescript - 在受约束的通用函数中混淆 "[ts] Type ... is not assignable to type [2322]"错误

转载 作者:行者123 更新时间:2023-12-04 13:01:59 32 4
gpt4 key购买 nike

我一直对下面代码中的 TypeScript 编译器错误 2322 感到困惑。

function broken<A extends {a: number}>() {
const foo: A = {a: 1}; // unexpected error: [ts] Type '{ a: number; }' is not assignable to type 'A'. [2322]
console.log (foo);
}

如果类型是非泛型的,类似的代码编译时不会出错。
function works() {
interface A {a: number};
const foo: A = {a: 1}; // no compiler error, as expected
console.log (foo);
}

为什么第一个函数编译失败?我认为我对接口(interface)和通用约束之间的区别有一些基本的误解。

https://codesandbox.io/s/vqx75yqx13

最佳答案

过了一会儿,我意识到了问题所在。将 TypeScript 错误 2322 翻译成简单的英语,这意味着:“您正在尝试将 A 的值设置为具有数字属性 a 但也可能具有其他属性 (!!!) 具有对象文字只有一个数字属性 a 。由于此对象文字缺少 A 的其他(潜在)属性,因此赋值失败。”

作为问题的说明,想象用一个真实类型替换 A:

interface A { a: number; b: string; };
const foo: A = { a: 1 }; // compiler error, as expected

如果泛型类型是特定类型,那么如果任何满足泛型约束(“具有数字属性 a”)的可能类型都可以工作,则编译器会抛出错误。

理论上,在这种情况下,TypeScript 可能会更智能,方法是检查生成的 foo 是否可能在代码的后面引起问题。例如,如果您对 foo 所做的唯一一件事是使用其 a 属性,并且您不向 foo 返回任何超出其约束的操作,例如将其传递给接受 A 的其他函数。

但似乎 TypeScript 还没有那么聪明——它没有考虑到你的代码的 future 。相反,它在赋值时检查所有可能的右侧类型是否满足左侧类型的约束。如果没有,它会抛出一个错误。

如果您确定代码不会导致问题(例如,因为您传入的值不只是扩展 A ,它实际上是 A 的实例),那么您可以将该值转换为 A 并且赋值将起作用.这是调用数据库等外部 API 时的常见模式,它可能返回无类型的 JSON,您可以将其转换为您知道的类型。像这样:
function alsoWorks1<A extends {a: number}>() {
const foo: A = {a: 1} as A;
console.log (foo);
}

或者您可以决定将其从泛型函数更改为非泛型函数。像这样:
function alsoWorks2() {
const bar = { a: 1 };
const foo = { a: bar.a }; // no error
console.log (foo);
}

关于typescript - 在受约束的通用函数中混淆 "[ts] Type ... is not assignable to type [2322]"错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54610445/

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