Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Typescript “令人困惑”;[ts]类型。。。不可分配给类型[2322]”;约束泛型函数中的错误_Typescript_Typescript Generics - Fatal编程技术网

Typescript “令人困惑”;[ts]类型。。。不可分配给类型[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); } 为什么第一个函数无法编译?我想我误解了接口和泛型约束之间的基本

我一直对下面代码中的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);
}
为什么第一个函数无法编译?我想我误解了接口和泛型约束之间的基本区别


过了一会儿,我意识到了这个问题。将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);
}