Den*_*stu 6 javascript typescript typescript1.7
我最近偶然发现了TypeScript中这种奇怪的(imo)行为.在编译期间,只有当接口没有必填字段时,如果预期变量的类型是接口,它才会抱怨多余的属性.链接到TypeScript Playground#1:http://goo.gl/rnsLjd
interface IAnimal {
name?: string;
}
class Animal implements IAnimal {
}
var x : IAnimal = { bar: true }; // Object literal may only specify known properties, and 'bar' does not exist in type 'IAnimal'
var y : Animal = { bar: true }; // Just fine.. why?
function foo<T>(t: T) {
}
foo<IAnimal>({ bar: true }); // Object literal may only specify known properties, and 'bar' does not exist in type 'IAnimal'
foo<Animal>({ bar: true }); // Just fine.. why?
Run Code Online (Sandbox Code Playgroud)
现在,如果你向IAnimal接口添加一个'强制'字段并在Animal类中实现它,它将开始抱怨'bar'是bot接口和类的多余属性.链接到TypeScript Playground#2:http://goo.gl/9wEKvp
interface IAnimal {
name?: string;
mandatory: number;
}
class Animal implements IAnimal {
mandatory: number;
}
var x : IAnimal = { mandatory: 0, bar: true }; // Object literal may only specify known properties, and 'bar' does not exist in type 'IAnimal'
var y : Animal = { mandatory: 0, bar: true }; // Not fine anymore.. why? Object literal may only specify known properties, and 'bar' does not exist in type 'Animal'
function foo<T>(t: T) {
}
foo<IAnimal>({ mandatory: 0, bar: true }); // Object literal may only specify known properties, and 'bar' does not exist in type 'IAnimal'
foo<Animal>({ mandatory: 0,bar: true }); // Not fine anymore.. why? Object literal may only specify known properties, and 'bar' does not exist in type 'Animal'
Run Code Online (Sandbox Code Playgroud)
如果有人有一些见解,为什么它的工作原理,请做.
我很好奇为什么会这样.
以下来自拉取请求的三个要点揭示了 TS 1.6 中在 Playground 中使用的新严格行为:
- 每个对象字面量最初都被认为是“新鲜的”。
- 当将新的对象字面量分配给变量或传递给非空目标类型的参数时[强调],对象字面量指定目标类型中不存在的属性是错误的。
- 当类型断言或对象字面量的类型被扩展时,新鲜感就会消失。
我在源代码function hasExcessProperties和function isKnownProperty注释中找到了:
Run Code Online (Sandbox Code Playgroud)// Check if a property with the given name is known anywhere in the given type. In an object type, a property // is considered known if the object type is empty and the check is for assignability, if the object type has // index signatures, or if the property is actually declared in the object type. In a union or intersection // type, a property is considered known if it is known in any constituent type. function isKnownProperty(type: Type, name: string): boolean { if (type.flags & TypeFlags.ObjectType) { const resolved = resolveStructuredTypeMembers(type); if (relation === assignableRelation && (type === globalObjectType || resolved.properties.length === 0) || resolved.stringIndexType || resolved.numberIndexType || getPropertyOfType(type, name)) { return true; } } else if (type.flags & TypeFlags.UnionOrIntersection) { for (const t of (<UnionOrIntersectionType>type).types) { if (isKnownProperty(t, name)) { return true; } } } return false; }
因此,第一个示例中的目标类型Animal(类)是一个空类型 - 它没有属性,因为您没有name在类中实现属性(因此resolved.properties.length === 0在函数中为 true isKnownProperty)。另一方面IAnimal已定义属性。
我可能从技术上描述了这种行为,但是……希望我说得很清楚,希望我在路上没有犯错误。
| 归档时间: |
|
| 查看次数: |
812 次 |
| 最近记录: |