您可以通过指定一个来完成此操作this
对应于类本身的参数。在静态方法中,this
指类本身。
static create<T extends Parent>(this: new (...args: any[]) => T, data: object) {...}
这里发生的事情是我们说的是this
类型,它将引用包含该方法的对象,在这种情况下,无论是哪个类对象create
被调用时,可以返回该类的实例类型的子类型。这是通过类型参数完成的T
,以及类对象将具有返回一个构造签名的归属T
,从而捕获任何派生类的实例类型。
这是完整的工作代码:
class Parent {
static create<T extends Parent>(this: new (...args: any[]) => T, data: object) {
let instance = new this;
for (let [key, value] of Object.entries(data)) {
instance[key as keyof T] = value;
}
return instance;
}
}
class Child extends Parent {
id: number | null = null;
}
let child = Child.create({ id: 1 });
console.log(child.id);
游乐场链接 https://www.typescriptlang.org/play?#code/MYGwhgzhAEAKYCcCmA7ALtA3gKGn6EaYaAlsNMMsUgDwAq0SAHmqgCYzzLoB8AFGgAWJCAC5oKJAHdofAHQLEAczHQwKAJ4BtALoBKaAF4e0OgBpobYmHEB7AEYArJMDQGc+T9BBIMJFITqwEhGEtLQQiIA3LheeABmtgiyPhhaANZIGhYAbmAgAK5IOtC28dAA8k4uaHKoaAgkSBB8VkR67rFxnv6BKMEZWWowmRplpiWG0HmFSDHd0AC+XV7IaAUIKNC9RP1zK8vL2KCQMADCwiBsjCzsnIj1WCskbOIoBQC29kjJAD4SBRAIFC7yBMSOqQol2uUwuJCuckoSGofEw21e0AAjEs9DFgLYArYfHIQLYlHxgNC5C9cUA
由于我们已经通过以下方式捕获了派生实例类型T
,我们可以细化create
通过调整 create 进一步提高类型安全性的方法如下:
static create<T extends Parent>(this: new (...args: any[]) => T, data: Partial<T>) {...}
这阻止我们传递,从而将任意属性分配给由create
方法同时提供智能感知。
完整代码:
class Parent {
static create<T extends Parent>(this: new (...args: any[]) => T, data: Partial<T>) {
let instance = new this;
for (let [key, value] of Object.entries(data)) {
const k = key as keyof T;
instance[k] = value as T[typeof k];
}
return instance;
}
}
class Child extends Parent {
id: number | null = null;
}
let child = Child.create({ id: 1 });
console.log(child.id);
游乐场链接 https://www.typescriptlang.org/play?#code/MYGwhgzhAEAKYCcCmA7ALtA3gKGn6EaYaAlsNMMsUgDwAq0SAHmqgCYzzLoB8AFGgAWJCAC5oKJAHdofAHQLEAczHQwKAJ4BtALoBKaAF4e0OgBpobYmHFdSYEPR4Gc+N9BBIMJFIXXAkIwlpaCERAG5cdzwAMwB7BFlPDC0AayQNCwA3BwBXJB1oOJjoAHkAIwArJGA0OVQ0BBIkCD4rIj0XKOi3YDjfDFSg9I01GBHi00ie9x8-FAC0wsNoHJB8sdMtNA0AByRJ1J1pnoBfbvdkNFyEFGg5ogWkE7xz8+xQSBgAYWEQNkYLHYnEQDSwFxIbHEKFyAFtykhEgAfCS5EAgIIw9GRd7JCh-AErX4kf5yShIah8TD3KHQACM0FOekifV8cU8chAcSUfGABLkkOZQA