Typescript 如何在通用占位符上使用提取
bar类上的Typescript 如何在通用占位符上使用提取,typescript,generics,Typescript,Generics,bar类上的extend保护未在foo类上强制执行 Argument of type '"bar"' is not assignable to parameter of type 'Extract<keyof T, string>'. 类型为“bar”的参数不能分配给类型为“Extract”的参数。 用于酒吧中的get和get2调用 class-foo{ 获取(a:摘录){ 返回“”; } } 接口IAttrs{ 条形图:布尔型; } 类栏扩展了foo{ 构造函数(){ 超级()
extend
保护未在foo类上强制执行
Argument of type '"bar"' is not assignable to parameter of type 'Extract<keyof T, string>'.
类型为“bar”的参数不能分配给类型为“Extract”的参数。
用于酒吧中的get和get2调用
class-foo{
获取(a:摘录){
返回“”;
}
}
接口IAttrs{
条形图:布尔型;
}
类栏扩展了foo{
构造函数(){
超级();
this.get('bar'))
this.get2('bar'))
}
get2(a:摘录){
返回“”;
}
}
类foobar扩展了foo{
构造函数(){
超级();
this.get('bar'))
}
}
我希望bar和foobar类都能编译;但是bar类有以下错误:
我使用的是typescript 3.2.2主要问题是,当
T
是一个未解析的泛型类型参数时,编译器不会(无论如何从TS3.5开始)执行识别“bar”所需的类型分析
可分配给提取
,即使T
被限制为扩展IAttrs
Extract
是一个编译器,并且编译器一般都是这样。也许这个特定的用例可以作为一个建议,但我怀疑它是否会被优先考虑
因此,我们需要要么使用已解析的条件类型,要么在非条件类型中使用未解析的类型参数
- 解析条件类型:由于
包括所有keyof T
,因此keyof IAttrs
类型相当于keyof T
。因此keyof T | keyof IAttrs
相当于有问题的类型。但由于Extract
是,因此它将被评估为Extract
。最右边的组成部分是一个已解析的条件类型,它将被急切地计算为“bar”。现在我们有了Extract | Extract
。未解析的条件类型仍然存在,但现在提取|“bar”
显式地成为联合的一部分。。。错误应该会消失“bar”
- 未解析的非条件类型:
类型是在TS2.8中使用条件类型引入的。它过滤具有约束的联合类型。在TS2.8之前,如果我们想要约束这样的类型,我们只需要使用。过去,工会的交叉点也是杂乱无章的,Extract
将评估为(“foo”;“bar”)和(“bar”;“baz”)
。如今,尽管它只达到了所需的(“foo”和“bar”)(“foo”和“baz”)“bar”(“bar”和“baz”)
。幸运的是,即使是未解决的类型参数也会在交叉口进行分析。。。也就是说,如果已知“bar”
可分配给X
和A
,则已知B
可分配给X
。因此,我们可以将A和B
更改为Extract
,错误也应该消失(keyof T)&string
class Foo<T> {
// intersection
get(a: keyof T & string) {
return "";
}
}
interface IAttrs {
bar: boolean;
}
class Bar<T extends IAttrs> extends Foo<T> {
constructor() {
super();
this.get("bar");
this.get2("bar");
}
// resolved conditional
get2(a: Extract<keyof T | keyof IAttrs, string>) {
return "";
}
}
class FooBar extends Foo<IAttrs> {
constructor() {
super();
this.get("bar");
}
}
class-Foo{
//交叉口
get(a:T和字符串的键){
返回“”;
}
}
接口IAttrs{
条形图:布尔型;
}
类栏扩展了Foo{
构造函数(){
超级();
这个。得到(“酒吧”);
本条第2款(“bar”);
}
//解析条件
get2(a:摘录){
返回“”;
}
}
类FooBar扩展了Foo{
构造函数(){
超级();
这个。得到(“酒吧”);
}
}
所有的编译都没有错误。好吧,希望这会有帮助;祝你好运 我认为当
t
仍然是泛型时,编译器无法将条件类型Extract
解析为有用的内容,即使您知道keyof t
必须至少包含“bar”
。我的建议是将Extract
改为Extract
,甚至(keyof T)&string
@jcalz,如果您添加注释作为解决方案,我会接受。我用`(keyof T)&string`来学习。非常感谢。