有没有办法在打字稿中实例化泛型文字类型?



我想做一些可能非正统的事情(如果我们说实话,几乎毫无用处(,所以我们来了:

我想将文本作为泛型参数传递,然后将其实例化。请考虑以下示例:

const log = console.log;
class Root<T = {}> {
// public y: T = {}; // this obviously doesn't work
// again this won't work because T is used a value. Even if it worked,
// we want to pass a literal
// public y: T = new T();
public x: T;
constructor(x: T) {
this.x = x;
}
}
class Child extends Root<{
name: "George",
surname: "Typescript",
age: 5
}> {
constructor() {
// Duplicate code. How can I avoid this?
super({
name: "George",
surname: "Typescript",
age: 5
});
}
foo() {
// autocomplete on x works because we gave the type as Generic parameter
log(`${this.x.name} ${this.x.surname} ${this.x.age}`); 
}
}

const main = () => {
const m: Child = new Child();
m.foo();
};
main();

这有效,但我必须传递两次文字。一次是泛型以自动完成工作,一次是在构造函数上进行初始化。呸。

另一种方法是在Child之外声明我的文字。喜欢这个:

const log = console.log;
class Root<T = {}> {
// public y: T = {}; // this obviously doesn't work
// again this won't work because T is used a value. Even if it worked,
// we want to pass a literal
// public y: T = new T(); 
public x: T;
constructor(x: T) {
this.x = x;
}
}
// works but ugh..... I don't like it. I don't want to declare things outside of my class
const literal = {
name: "George",
surname: "Typescript",
age: 5
}
class Child extends Root<typeof literal> {
constructor() {
super(literal);
}
foo() {
// autocomplete on x works because we gave the type as Generic parameter
log(`${this.x.name} ${this.x.surname} ${this.x.age}`); 
}
}

const main = () => {
const m: Child = new Child();
m.foo();
};
main();

有没有神奇的方法可以实例化 Generic 类型,而无需通过构造函数再次显式提供它?

您可以使用中间包装器来负责扩展泛型和调用构造函数:

function fromRoot<T>(x: T) {
return class extends Root<T> {
constructor() {
super(x)
}
}
}

然后:

class Child extends fromRoot({
name: "George",
surname: "Typescript",
age: 5
}) { etc }

噗嗤

你需要知道,编译的Javascript不知道泛型,因此你不能使用它们来创建新对象。

另外,如果类被限制为特定对象,我看不出Child类的意义 - 你为什么不定义你的Child期望的type,然后用该类型的特定实例实例实例化孩子?

type MyType = {
name: string
surname: string
age: number
}
class Child extends Root<MyType> {
foo() {
// autocomplete on x works because we gave the type as Generic parameter
console.log(`${this.x.name} ${this.x.surname} ${this.x.age}`);
}
}
const child = new Child({
name: "George",
surname: "Typescript",
age: 5
})

如果要重用该特定Child只需将该特定child实例导出即可。

请看游乐场。

最新更新