Я хочу сделать что-то, что, вероятно, неортодоксально (и погранично бесполезно, если мы честны), так что мы идем:
Я хочу передать литерал в качестве параметра Generic, а затем создать его экземпляр. Рассмотрим следующий пример:
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();
Есть ли какой-нибудь магический способ создания экземпляра универсального типа без явного предоставления его снова через конструктор?