bar类上的extend
保护措施未在foo类上强制执行。
Argument of type '"bar"' is not assignable to parameter of type 'Extract<keyof T, string>'.
用于bar中的get和get2调用。
class foo<T> {
get(a: Extract<keyof T, string>) {
return '';
}
}
interface IAttrs {
bar: boolean;
}
class bar<T extends IAttrs> extends foo<T>{
constructor() {
super();
this.get('bar')
this.get2('bar')
}
get2(a: Extract<keyof T, string>) {
return '';
}
}
class foobar extends foo<IAttrs>{
constructor() {
super();
this.get('bar')
}
}
我希望bar和foobar类都可以编译;但是bar类具有以下错误:
我正在使用打字稿3.2.2
答案 0 :(得分:0)
主要问题是,当T
是一个无法解析的泛型类型参数时,编译器(无论如何从TS3.5开始)不会执行识别{{即使"bar"
受约束扩展Extract<keyof T, string>
,也可以将1}}分配给T
。 IAttrs
是conditional type,编译器通常是defers most analysis of unresolved conditional types。也许可以将此特定用例作为filed in GitHub的建议,但我怀疑它会被优先考虑。
因此,我们需要使用可解析的条件类型,或者需要在非条件类型中使用未解析的类型参数。
已解析的条件类型:由于Extract
包含所有keyof T
,因此类型keyof IAttrs
等效于keyof T
。因此keyof T | keyof IAttrs
等同于有问题的类型。但是由于Extract<keyof T | keyof IAttrs, string>
是distributive,它将被评估为Extract
。最右边的组成部分是可解析的条件类型,将急切地将其评估为Extract<keyof T, string> | Extract<keyof IAttrs, string>
。现在我们有了"bar"
。尚未解决的条件类型仍然存在,但是现在Extract<keyof T, string> | "bar"
明确地是联合的一部分……错误应该消失了。
未解决的非条件类型:"bar"
类型是在TS2.8中引入的,带有条件类型。它过滤带有约束的联合类型。在TS2.8之前,如果我们想约束这样的类型,我们只需要使用intersections。也曾经是联合的交集很杂乱,Extract
的计算结果为("foo" | "bar") & ("bar" | "baz")
。如今,它可以根据需要将reduced调整为("foo" & "bar") | ("foo" & "baz") | "bar" | ("bar" & "baz")
。幸运的是,即使是未解析的类型参数也会在相交处进行分析……也就是说,如果已知"bar"
可同时分配给X
和A
,那么B
也是已知的可分配给X
。因此我们可以将A & B
更改为Extract<keyof T, string>
,错误也应该消失。
让我们看一下同时做这两个事情的一些修改后的代码:
(keyof T) & string
所有编译都没有错误。好的,希望能有所帮助;祝你好运!