值得注意的是,这an implements
clause doesn't actually affect the type of the class to which it's applied个.类只遵守已实现的类型的check,除此之外,判断所有内容的行为就像没有子句一样.因此,当涉及到类型推断时,
class A implements B<string> { }
完全相同于
class A { }
这意味着A
就是an empty class,你可以期待奇怪的事情发生.
特别是,当您try 使用conditional type inference到infer
的T
,其中A extends B<T>
,它将不会像预期的那样工作.如果B<T>
的子类型没有bla
属性,则T
是unused,这是prevents inference.A
可赋值给B<T>
for any possible 104.编译器没有理由优先 Select string
而不是任何其他类型,因此推理失败,并回退到the unknown
type:
type ThisShouldBeString = A extends B<infer T> ? T : never;
//type ThisShouldBeString = unknown ?
为了使这可能起作用,您需要确保A
和B<T>
之间的比较是100 dependence对T
.例如:
class A /* implements B<string> */ {
declare bla?: string;
}
现在A
有一个 struct ,可以有意义地将其与B<T>
进行比较,即使没有implements
从句(同样,这不会影响事情).推论成功了:
type ThisShouldBeString = A extends B<infer T> ? T : never;
//type ThisShouldBeString = string ?
万岁!
顺便说一句,这与作为JavaScript发出的A
版本没有任何关系.假设我有declare
d个bla
属性,它甚至不会在运行时出现.A
的两个版本都将编译成类似class A {}
的版本.它们之间的区别只是在静态类型系统上.
Playground link to code个