繁体   English   中英

在不指定类型的情况下实例化TypeScript通用类

[英]Instantiating TypeScript generic class without specifying type

如果我创建一个通用类

class Generic<T> {
     prop: T;
}

如果不在类型中指定T ,就不允许我输入内容

// Generic type 'Generic<T>' requires 1 type argument(s).
const val: Generic = new Generic(); 

但是如果我使用类型推断,它不会抱怨,它可以实例化它

const val = new Generic();
// field prop is not of type any, we can't access any properties on it
// val.prop.anything -> Compiler error
// val.prop.toString() -> No error, is it a string?
// val.prop.length -> Compiler error, not a string, just assumes that everything has a toString (based on boxing)

是否指定了此行为? 这背后的原因是什么?

背景

Angular2有一个EventEmitter ,它需要事件的参数类型。 但是,对于某些事件,您不传递任何参数,在这种情况下,我们一直在使用EventEmitter<void> 但是,我刚刚注意到,您可以仅定义发射器而无需指定类型, new EventEmitter()可以工作。 这种方法的缺点是,如果您将参数传递给emitter.emit('something') ,编译器将不会抱怨。 这不是我感兴趣的,只是背景,因此读者可以了解问题的出处。

游乐场 https://www.typescriptlang.org/play/#src=class%20Generic%3CT%3E%20%7B%0D%0A%20%20%20%20prop%3A%20T%3B%0D%0A% 7D%0D%0A%0D%0Aconst%20val%3A%20Generic%20%3D%20new%20Generic()%3B%0D%0A%0D%0Aconst%20val2%20%3D%20new%20Generic()%3B% 0D 0A%%0D%0Aval2.prop.test%20%3D%201%3B

以下两个语句是等效的...

const val: Generic<{}> = new Generic();
const val2 = new Generic();

在第一种情况下,从左侧的类型推断出在右侧省略的type参数。

在第二种情况下,您最终得到的是对象类型,因为无法推断出更具体的信息。

此处的规则是变量的类型必须满足通用类型参数。 当您使用const val: Generic = new Generic(); type参数不满足-您无法要求对其进行推断,因为您已决定对变量进行注释。

因此,两个允许的方案是:

  1. 用类型注释自己指定(整个)类型
  2. 允许(整个)类型由编译器推断

为了使后面的示例生效,您有两个选择。

选项1 ...如果您真的不想限制类型,请动态选择...

const val2 = new Generic<any>();
val2.prop.test = 1;

或者......选项2 ...如果想限制类型,指定它。

const val2 = new Generic<{ test: number }>();
val2.prop.test = 1;

最后,在许多情况下,您无需指定type参数,因为可以根据上下文进行推断。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM