首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >新EventEmitter()与新EventEmitter<Something>()

新EventEmitter()与新EventEmitter<Something>()
EN

Stack Overflow用户
提问于 2018-02-03 10:57:47
回答 2查看 5.1K关注 0票数 2

假设我有这样的代码:

代码语言:javascript
复制
export class ProductsListComponent {
  @Output() onProductSelected: EventEmitter<Product>;

  constructor() { 
    this.onProductSelected = new EventEmitter();
  }
}

这是EventEmitter使用的一些例子。我不明白为什么我们首先声明onProductSelect显式地声明是EventEmitter承载了Product实例,然后我们只使用new EventEmitter()实例化它。为什么不new EventEmitter<Product>()

我认为在C#中,我必须采用第二种方式,否则如果EventEmitter是泛型的,它就不会编译。为什么TypeScript不需要这样做呢?

//编辑:

进一步澄清我的问题。在以下方面有什么区别:

代码语言:javascript
复制
@Output() onProductSelected: EventEmitter<Product>;
this.onProductSelected = new EventEmitter();

代码语言:javascript
复制
@Output() onProductSelected: EventEmitter;
this.onProductSelected = new EventEmitter();
EN

回答 2

Stack Overflow用户

发布于 2018-02-03 18:54:20

正如在文献章节中解释的那样,类型参数推断发生在没有为泛型类或函数指定类型时。

函数可以从其参数或返回类型推断T类型,而类可以从构造函数参数或返回类型推断T类型:

代码语言:javascript
复制
function foo<T>(v: T) { return v }
foo(1); // T inferred to number

class Foo<T> {
  constructor(v: T) {}
}
new Foo(1); // T inferred to number

如果没有什么可推断的,T将被推断为空对象{} 出于某种原因

代码语言:javascript
复制
class Foo<T> {
  foo(v: T) {}
}

new Foo().foo(1); // T inferred to {}

为了避免对{}的推断,可以提供默认类型:

代码语言:javascript
复制
class Foo<T = string> {
  foo(v: T) {}
}

new Foo().foo(1); // type error

如果泛型类或函数不应该与默认类型一起使用,则可以指定一些不可能的类型:

代码语言:javascript
复制
class Foo<T = never> {
  foo(v: T) {}
}

new Foo(); // no type error, T isn't involved
new Foo().foo(<any>1); // type error

由于EventEmitter泛型类没有指定默认类型,因此后者被推断为{}。这通常不会有问题,因为emit唯一受泛型类型影响的方法。。由于可以强迫所有非空类型为对象类型,这通常不会导致类型错误--只要忽略空类型。

对于缺省类型和空值的EventEmitter编译器选项将是一个问题:

代码语言:javascript
复制
const ee = new EventEmitter();
ee.emit(null); // type error

因此,对于全面的EventEmitter,不应依赖默认类型,而应将其实例化为:

代码语言:javascript
复制
const ee = new EventEmitter<any>();
票数 4
EN

Stack Overflow用户

发布于 2018-02-03 11:01:39

EventEmitter()将与EventEmitter<any>()一样工作。如果您在ProductsListComponents的选择器上用HTML绘制这幅图,那么您可以侦听onProductSelected事件,并在发生这种情况时分配一个类似onSelected的操作。默认情况下,您将得到一个新的EventEmitter<any>(),定义一个any类型的变量是类型记录中的一般方法。

代码语言:javascript
复制
<product-list (onProductSelected)="onSelected($event)"> </product-list>

所以每次你给你的孩子打电话

代码语言:javascript
复制
this.onProductSelected.emit("hello");
this.onProductSelected.emit(1);

父函数onSelected($event)将被调用,您可以对该数据执行任何操作。

如果您只期望将一种类型的数据输出给父类型,以便它能够进一步处理它,那么您就需要坚持特定的数据类型。

代码语言:javascript
复制
onProductSelected: Product = new EventEmitter<Product>(); 
products: Product[];

然后,在代码中的某个地方,您可以触发发出

代码语言:javascript
复制
this.onProductSelected.emit(this.products[1]);

添加了一个stackblitz示例

关于你最新的问题

@Output() onProductSelected: EventEmitter;是一个错误,因为您在这里声明类型(在:之后,在=之前),与定义类型(在=之后)相反,当您将它声明为EventEmitter时,确实需要一个参数<type>

如果您声明了EventEmitter的类型,那么编译器将确保您不会发出除了Product之外的任何东西,或者您声明它是什么类型。

代码语言:javascript
复制
@Output() onProductSelected: EventEmitter<Product>;
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48596562

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档