То, что вы ищете здесь, является чем-то ближе к mixin , чем стандартное наследование. Но универсальные миксины из interface X<T> extends T
сорта не поддерживаются TypeScript .
Вы можете создать объект с именем SomeClass
и универсальный тип с именем SomeClass<T>
это, с некоторыми утверждениями типа, можно использовать таким образом, но вы сталкиваетесь с некоторыми ограничениями. Вот как я могу это сделать:
class _SomeClass<T> {
constructor(t: T) {
Object.assign(this, t);
}
// inside here we don't know about properties of T, though
// so you'll have to do assertions
get<K extends keyof T>(k: K): T[K] {
return (this as any as T)[k]; // assertion
}
}
type SomeClass<T> = T & _SomeClass<T>;
const SomeClass = _SomeClass as new <T>(t: T) => SomeClass<T>;
Класс _SomeClass<T>
является универсальным, но сам по себе не реализует T
. Конструктор присваивает свойства T
объекту this
(вам нужно что-то подобное этому назначению, чтобы получить действительный T
во время выполнения). Внутри реализации _SomeClass<T>
вам нужны утверждения, когда вы пытаетесь получить доступ к любым свойствам T
на this
(так что this as any as T
или this as this & T
ваши друзья).
Тогда тип SomeClass<T>
определяется как пересечение из _SomeClass<T>
и T
, а затем значение SomeClass
является просто конструктором _SomeClass
, но мы утверждаем, чтоон действует как конструктор SomeClass<T>
.
Давайте посмотрим, как он работает:
interface Props {
a: number;
b: boolean;
}
const obj = new SomeClass<Props>({ a: 1, b: true });
console.log(obj.a); // 1
console.log(obj.get("a")); // 1
interface Props2 {
some: string;
other: number;
props: boolean;
}
const obj2 = new SomeClass<Props2>({ some: "", other: 2, props: false });
Те, которые компилируются с IntelliSense, как вы ожидаете.
Есть еще ограничения,курс. TypeScript действительно позволяет вам extends
классов, где имена ключей известны статически. Так что если вам нужен общий подкласс из SomeClass
, вам не повезет:
class Nope<T> extends SomeClass<T> { // error!
/* Base constructor return type 'SomeClass<T>' is
not an object type or intersection of object types
with statically known members. */
}
A бетон подкласс будет работать (до тех пор, пока keyof T
известен статически):
class Okay extends SomeClass<Props> {
}
Хорошо, надеюсь, это поможет;удачи!
Ссылка на код