未强制执行泛型的打字稿类型保护
Typescript typeguards for generics not enforced
interface Foo {
bar() : Promise<string>;
}
class MyFoo implements Foo {
bar() : string {
return "";
}
}
class MyFoo2 implements Foo {
bar() : Promise<number> {
return new Promise<number>(null);
}
}
上面的两种实现不应该都导致错误吗?
- MyFoo 确实会出错,因为它 return 是字符串而不是 Promise
- MyFoo2 return是一个 promise,但是类型错误,并且没有错误 -- 为什么?
我能说的是 TypeScript 似乎检查 return 类型的成员而不是声明的类型。但是有没有办法以需要实现 return 正确类型的方式来声明此接口?
edit: 似乎是因为 es6 接口 Promise
定义了像 then() : Promise<T>
这样的成员,但没有像 foo(): T
这样的成员,所以类型检查不起作用。如果我用我的自定义通用接口模拟它,如果接口包含类型 T
的成员,但不包含类型 T
的泛型,它将正确出错
这是当前稳定版 TypeScript 中的一个错误。
来源:
- https://github.com/Microsoft/TypeScript/issues/12023
- https://github.com/Microsoft/TypeScript/issues/10524
- https://github.com/Microsoft/TypeScript/issues/10785
它已经修复,将包含在未来的版本 (2.1) 中。
我自己也试过:
D:\Practice\TypeScript\ts-test>npm install -g typescript
C:\Users\dezsi\AppData\Roaming\npm\tsc -> C:\Users\dezsi\AppData\Roaming\npm\node_modules\typescript\bin\tsc
C:\Users\dezsi\AppData\Roaming\npm\tsserver -> C:\Users\dezsi\AppData\Roaming\npm\node_modules\typescript\bin\tsserver
C:\Users\dezsi\AppData\Roaming\npm
└── typescript@2.0.10
D:\Practice\TypeScript\ts-test>C:\Users\dezsi\AppData\Roaming\npm\tsc.cmd --version
Version 2.0.10
D:\Practice\TypeScript\ts-test>C:\Users\dezsi\AppData\Roaming\npm\tsc.cmd --target ES6 app.ts
D:\Practice\TypeScript\ts-test>npm install -g typescript@next
C:\Users\dezsi\AppData\Roaming\npm\tsc -> C:\Users\dezsi\AppData\Roaming\npm\node_modules\typescript\bin\tsc
C:\Users\dezsi\AppData\Roaming\npm\tsserver -> C:\Users\dezsi\AppData\Roaming\npm\node_modules\typescript\bin\tsserver
C:\Users\dezsi\AppData\Roaming\npm
└── typescript@2.2.0-dev.20161122
D:\Practice\TypeScript\ts-test>C:\Users\dezsi\AppData\Roaming\npm\tsc.cmd --version
Version 2.2.0-dev.20161122
D:\Practice\TypeScript\ts-test>C:\Users\dezsi\AppData\Roaming\npm\tsc.cmd --target ES6 app.ts
app.ts(5,7): error TS2420: Class 'MyFoo2' incorrectly implements interface 'Foo'.
Types of property 'bar' are incompatible.
Type '() => Promise<string>' is not assignable to type '() => Promise<number>'.
Type 'Promise<string>' is not assignable to type 'Promise<number>'.
Type 'string' is not assignable to type 'number'.
在这里你可以看到尝试使用版本 2.0.10 没有给我一个错误,而最新的 2.2.0-dev.20161122 正确报告 Type 'string' is not assignable to type 'number'
.
interface Foo {
bar() : Promise<string>;
}
class MyFoo implements Foo {
bar() : string {
return "";
}
}
class MyFoo2 implements Foo {
bar() : Promise<number> {
return new Promise<number>(null);
}
}
上面的两种实现不应该都导致错误吗?
- MyFoo 确实会出错,因为它 return 是字符串而不是 Promise
- MyFoo2 return是一个 promise,但是类型错误,并且没有错误 -- 为什么?
我能说的是 TypeScript 似乎检查 return 类型的成员而不是声明的类型。但是有没有办法以需要实现 return 正确类型的方式来声明此接口?
edit: 似乎是因为 es6 接口 Promise
定义了像 then() : Promise<T>
这样的成员,但没有像 foo(): T
这样的成员,所以类型检查不起作用。如果我用我的自定义通用接口模拟它,如果接口包含类型 T
的成员,但不包含类型 T
这是当前稳定版 TypeScript 中的一个错误。
来源:
- https://github.com/Microsoft/TypeScript/issues/12023
- https://github.com/Microsoft/TypeScript/issues/10524
- https://github.com/Microsoft/TypeScript/issues/10785
它已经修复,将包含在未来的版本 (2.1) 中。
我自己也试过:
D:\Practice\TypeScript\ts-test>npm install -g typescript
C:\Users\dezsi\AppData\Roaming\npm\tsc -> C:\Users\dezsi\AppData\Roaming\npm\node_modules\typescript\bin\tsc
C:\Users\dezsi\AppData\Roaming\npm\tsserver -> C:\Users\dezsi\AppData\Roaming\npm\node_modules\typescript\bin\tsserver
C:\Users\dezsi\AppData\Roaming\npm
└── typescript@2.0.10
D:\Practice\TypeScript\ts-test>C:\Users\dezsi\AppData\Roaming\npm\tsc.cmd --version
Version 2.0.10
D:\Practice\TypeScript\ts-test>C:\Users\dezsi\AppData\Roaming\npm\tsc.cmd --target ES6 app.ts
D:\Practice\TypeScript\ts-test>npm install -g typescript@next
C:\Users\dezsi\AppData\Roaming\npm\tsc -> C:\Users\dezsi\AppData\Roaming\npm\node_modules\typescript\bin\tsc
C:\Users\dezsi\AppData\Roaming\npm\tsserver -> C:\Users\dezsi\AppData\Roaming\npm\node_modules\typescript\bin\tsserver
C:\Users\dezsi\AppData\Roaming\npm
└── typescript@2.2.0-dev.20161122
D:\Practice\TypeScript\ts-test>C:\Users\dezsi\AppData\Roaming\npm\tsc.cmd --version
Version 2.2.0-dev.20161122
D:\Practice\TypeScript\ts-test>C:\Users\dezsi\AppData\Roaming\npm\tsc.cmd --target ES6 app.ts
app.ts(5,7): error TS2420: Class 'MyFoo2' incorrectly implements interface 'Foo'.
Types of property 'bar' are incompatible.
Type '() => Promise<string>' is not assignable to type '() => Promise<number>'.
Type 'Promise<string>' is not assignable to type 'Promise<number>'.
Type 'string' is not assignable to type 'number'.
在这里你可以看到尝试使用版本 2.0.10 没有给我一个错误,而最新的 2.2.0-dev.20161122 正确报告 Type 'string' is not assignable to type 'number'
.