简体   繁体   English

类型声明适用于对象文字,但不适用于类实现

[英]Type declaration works for object literal, but not for class implementation

I want a type to represent a coordinate. 我想要一个类型来代表一个坐标。 The type I have have applied to an interface works for an object but not a class. 我已应用到接口的类型适用于对象,但不适用于类。

type ICoord = [number, number]

type MyInterface = {
    a: ICoord
}

var obj: MyInterface = { // works
    a: [0, 0]
}

class C implements MyInterface { // gets below compilation error
    a = [0, 0]
}

Property 'a' in type 'C' is not assignable to the same property in base type 'MyInterface'. Type 'number[]' is missing the following properties from type '[number, number]': 0, 1

Why can't I assign [0, 0] to a ? 为什么不能将[0, 0]分配给a

[TypeScript Playground] [TypeScript游乐场]

The type of a is being inferred as number[] which is not assignable to the tuple [number, number] . 的类型的a被推断为number[]这是不分配给元组[number, number] Explicitly defining the type as ICoord for a appears to work: 显式定义的类型ICoord对于a似乎工作:

type ICoord = [number, number];

type MyInterface = {
  a: ICoord;
}

class C implements MyInterface {
  a: ICoord = [0, 0];
}

TypeScript Playground TypeScript游乐场

This has to do with contextual typing. 这与上下文类型有关。

Typescript usses the expected type of an expression ( MyInterface in this case) to make better inferences about object literals (also about function parameters). Typescript使用表达式的预期类型(在这种情况下为MyInterface )来更好地推断对象文字(还涉及函数参数)。 This is why assigning an object literal works well and the array literals is typed as a tuple type. 这就是为什么分配对象文字可以很好地工作并且将数组文字键入为元组类型的原因。

For classes things are a bit different. 对于班级,情况有所不同。 The implements clause is just used to check that the class correctly implements the interface AFTER the class has been independently typed. implements子句仅用于在类被独立键入后检查类是否正确实现了接口。 The implements keyword does not create any contextual typing for any of the class members. implements关键字不会为任何类成员创建任何上下文类型。 This is also the reason you have to specify function parameters types even if they would be obvious from the interface or base class. 这也是您必须指定函数参数类型的原因,即使它们在接口或基类中是显而易见的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM