我很难理解TypeScript
泛型与类的这种行为。
打字本
interface IProvider<K extends {[key: string]: any}> {
data: K;
}
class Provider<T extends {[key: string]: any}> implements IProvider<T> {
data: T;
constructor(arg?: T) {
this.data = arg || {}; // This is not allowed.
}
}
type User = {
[key: string]: any
}
const x = new Provider<User>();
错误是:
Type 'T | {}' is not assignable to type 'T'.
'T | {}' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '{ [key: string]: any; }'.
Type '{}' is not assignable to type 'T'.
'{}' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '{ [key: string]: any; }'.
但是,如果我删除了可选操作符,它就能正常工作。
打字本
class Provider<T extends {[key: string]: any}> implements IProvider<T> {
data: T;
constructor(arg: T) { // no optional
this.data = arg || {}; // Now it works.
}
}
请帮我解释一下,非常感谢!
2条答案
按热度按时间798qvoo81#
这个错误正确地警告你潜在的不合理性。
考虑下面的场景,其中
User
类型有一个string
类型的属性a
,当arg
是可选的,我们不需要传递任何对象给构造函数,构造函数将用{}
初始化数据。访问
x.data.a
将导致运行时值为undefined
,即使我们将其键入为string
。如果我们将构造函数参数设为强制性的,就不会发生这种情况。
Playground
vhmi4jdf2#
今天是你的幸运日。
我不想谈论为什么它不工作,但解释泛型的概念,为什么,以及我们应该在哪里使用它。
1-行为
例如,我有三个对象,
我有一个Printer类,它可以打印任何实现如下Printable接口的对象。
2-数据和行为