是否可以从其通用类型自动生成 class 属性?
Is it possible to auto generate class properties from its generic type?
在 TypeScript 中是否有任何方法可以生成 class 其泛型类型的属性,如下所示:
class SomeClass<T> {
// Read props from T somehow here?
}
interface Props {
a: number;
b: boolean;
}
const obj = new SomeClass<Props>;
// So now both obj.a and obj.b are available in autocomplete with correct types from Props interface
interface Props2 {
some: string;
other: number;
props: boolean;
}
const obj2 = new SomeClass<Props2>;
// Now only three props from Props2 are available to obj2
我不想添加类似
的内容
class SomeClass {
[prop: string]: any
}
因为它只允许在那里分配任何 属性,我想从通用类型中获得固定列表
类 中不能使用映射类型。但是,在这里构建答案:,您可以创建一个函数来创建一个对象,其定义的属性与这样的接口匹配:
interface Props {
a: number;
b: boolean;
}
function build<T>(value?: T): T {
return Object.assign({}, value);
}
const obj = build<Props>();
// obj contains typed a and b properties
// Or, pass in default values
// const obj = build<Props>({ a: 2, b: false });
您在这里寻找的是更接近 mixin than standard inheritance. But generic mixins of the interface X<T> extends T
variety are not supported by 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>;
class _SomeClass<T>
是通用的,但它本身并不知道实现 T
。构造函数将 T
对象中的属性分配给 this
(您需要像这样的分配才能在 运行 时获得有效的 T
)。在 _SomeClass<T>
实现中,每当您尝试访问 this
上 T
的任何属性时都需要断言(因此 this as any as T
或 this as this & T
是您的朋友)。
那么类型SomeClass<T>
定义为_SomeClass<T>
和T
的intersection,那么值SomeClass
就是[=31] =] 构造函数,但我们断言它的行为类似于 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
classes,其中键名是静态已知的。因此,如果您需要 SomeClass
的通用 subclass,那您就不走运了:
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 concrete subclass 将起作用(只要 keyof T
是静态已知的):
class Okay extends SomeClass<Props> {
}
好的,希望对您有所帮助;祝你好运!
在 TypeScript 中是否有任何方法可以生成 class 其泛型类型的属性,如下所示:
class SomeClass<T> {
// Read props from T somehow here?
}
interface Props {
a: number;
b: boolean;
}
const obj = new SomeClass<Props>;
// So now both obj.a and obj.b are available in autocomplete with correct types from Props interface
interface Props2 {
some: string;
other: number;
props: boolean;
}
const obj2 = new SomeClass<Props2>;
// Now only three props from Props2 are available to obj2
我不想添加类似
的内容class SomeClass {
[prop: string]: any
}
因为它只允许在那里分配任何 属性,我想从通用类型中获得固定列表
类 中不能使用映射类型。但是,在这里构建答案:
interface Props {
a: number;
b: boolean;
}
function build<T>(value?: T): T {
return Object.assign({}, value);
}
const obj = build<Props>();
// obj contains typed a and b properties
// Or, pass in default values
// const obj = build<Props>({ a: 2, b: false });
您在这里寻找的是更接近 mixin than standard inheritance. But generic mixins of the interface X<T> extends T
variety are not supported by 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>;
class _SomeClass<T>
是通用的,但它本身并不知道实现 T
。构造函数将 T
对象中的属性分配给 this
(您需要像这样的分配才能在 运行 时获得有效的 T
)。在 _SomeClass<T>
实现中,每当您尝试访问 this
上 T
的任何属性时都需要断言(因此 this as any as T
或 this as this & T
是您的朋友)。
那么类型SomeClass<T>
定义为_SomeClass<T>
和T
的intersection,那么值SomeClass
就是[=31] =] 构造函数,但我们断言它的行为类似于 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
classes,其中键名是静态已知的。因此,如果您需要 SomeClass
的通用 subclass,那您就不走运了:
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 concrete subclass 将起作用(只要 keyof T
是静态已知的):
class Okay extends SomeClass<Props> {
}
好的,希望对您有所帮助;祝你好运!