Typescript “令人困惑”;[ts]类型。。。不可分配给类型[2322]”;约束泛型函数中的错误
我一直对下面代码中的TypeScript编译器错误2322感到困惑Typescript “令人困惑”;[ts]类型。。。不可分配给类型[2322]”;约束泛型函数中的错误,typescript,typescript-generics,Typescript,Typescript Generics,我一直对下面代码中的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 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);
}
为什么第一个函数无法编译?我想我误解了接口和泛型约束之间的基本区别
过了一会儿,我意识到了这个问题。将TypeScript错误2322翻译成简单的英语,这意味着:“您试图将
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似乎还没有那么聪明——它并没有展望代码的未来。相反,它会在赋值点检查所有可能的右侧类型是否都满足左侧类型的约束。如果不满足,则会抛出错误
如果您确信代码不会引起问题(例如,因为您传入的值不仅仅扩展了a
,它实际上是a
的一个实例)然后,您可以将值强制转换为,赋值将起作用。这是调用外部API(如数据库)时的常见模式,可能会返回非类型化JSON,您可以将其转换为您知道的类型。如下所示:
function alsoWorks1<A extends {a: number}>() {
const foo: A = {a: 1} as A;
console.log (foo);
}
我添加了一个类似的问题,但我无法了解解决方案。对我来说,这应该是一个Typescript错误。您正在定义函数返回类型的约束。如果返回变量的类型有效地尊重该约束,则仅此而已。它应该编译。此代码决不会带来未定义的行为和
作为一个
,您添加到行中的代码应该是不必要的。只有当提供给函数的有效类型不只是定义的约束时,此代码才会编译失败。而且它应该在调用站点失败,而不是在函数定义中失败。非常感谢!我正在使用并且遇到了问题。我需要删除u typename阿波罗自动添加的字段:但随后得到了ts(2322)
错误。强制转换为数字最终起作用:const-lat:number=mapOptions.center.lat作为数字;const-lng:number=mapOptions.center.lng作为数字;const-mapOptions-cleanned={center:new google.maps.LatLng({lat,lng}),zoom:mapOptions.zoom,};
I
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);
}