Lor*_*eno 3 javascript generics typescript angular
假设我有这个代码:
export class ProductsListComponent {
@Output() onProductSelected: EventEmitter<Product>;
constructor() {
this.onProductSelected = new EventEmitter();
}
}
Run Code Online (Sandbox Code Playgroud)
这是一些用法示例EventEmitter。我不明白为什么首先我们声明 onProductSelect 明确指出它EventEmitter携带 Product 实例,然后我们仅使用new EventEmitter(). 为什么不new EventEmitter<Product>()?
我认为在 C# 中我必须采用第二种方式,因为否则如果EventEmitter是通用的,它就无法编译。为什么 TypeScript 不需要这样?
//编辑:
进一步澄清我的问题。有什么区别:
@Output() onProductSelected: EventEmitter<Product>;
this.onProductSelected = new EventEmitter();
Run Code Online (Sandbox Code Playgroud)
和
@Output() onProductSelected: EventEmitter;
this.onProductSelected = new EventEmitter();
Run Code Online (Sandbox Code Playgroud)
如文档章节中所述中所解释的,当没有为泛型类或函数指定类型时,就会发生类型参数推断。
函数可以T从其参数或返回类型推断类型,类可以T从构造函数参数或返回类型推断类型:
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
Run Code Online (Sandbox Code Playgroud)
如果没有什么可推断的,则由于某种原因T被推断为空对象:{}
class Foo<T> {
foo(v: T) {}
}
new Foo().foo(1); // T inferred to {}
Run Code Online (Sandbox Code Playgroud)
为了避免推断{},可以提供默认类型:
class Foo<T = string> {
foo(v: T) {}
}
new Foo().foo(1); // type error
Run Code Online (Sandbox Code Playgroud)
如果泛型类或函数不应该与默认类型一起使用,则可以指定一些不可能的类型:
class Foo<T = never> {
foo(v: T) {}
}
new Foo(); // no type error, T isn't involved
new Foo().foo(<any>1); // type error
Run Code Online (Sandbox Code Playgroud)
由于EventEmitter泛型类没有指定默认类型,因此后者被推断为{}. 通常不会有问题,因为这emit是唯一受泛型类型影响的方法。由于所有非空类型都可以强制转换为对象类型,因此只要忽略空类型,这通常不会导致类型错误。
strictNullChecksEventEmitter对于默认类型和空值,编译器选项将是一个问题:
const ee = new EventEmitter();
ee.emit(null); // type error
Run Code Online (Sandbox Code Playgroud)
因此,对于全面而言,EventEmitter它不应该依赖于默认类型并实例化为:
const ee = new EventEmitter<any>();
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
7438 次 |
| 最近记录: |