Sep*_*eed 3 typescript typescript-typings
我有一些包含所有公共成员(本质上是一个结构)的类,我想存储它的数据:
class SomeClass {
public foo: string;
public bar: string;
public getFooBar() {
return this.foo + this.bar;
}
}
Run Code Online (Sandbox Code Playgroud)
作为存储检索的一部分,我希望有一个正确定义它的接口,例如:
interface ISomeClassData {
foo: string;
bar: string;
// notice there is no getFooBar()
}
const test: ISomeClassData = magic();
if ("getFooBar" in test === false) {
return "Success. This is an interface, and not a class";
}
Run Code Online (Sandbox Code Playgroud)
做这种事情的一种典型(但不适用)的方式如下:
interface ISomeClassData {
foo: string;
bar: string;
}
class SomeClass extends ISomeClassData {
// code omitted
}
Run Code Online (Sandbox Code Playgroud)
在我的场景中,类中公共属性的数量非常大,并且将某些内容添加到类中而不添加到接口中将非常非常容易。相反,我想做的是从类派生接口。
是否可以从 Typescript 中的类属性(省略方法)派生接口?
想象的例子:
type ISomeClassData = JustThePublicProperties<SomeClass>
Run Code Online (Sandbox Code Playgroud)
听起来您想要所有不是函数的键,并且您想仅用这些键构建一个对象。
// Get the keys that are not functions. We consider these data.
type ClassDataKeys<T> = {
// Iterate over each property.
[K in keyof T]:
// If the property is a function...
T[K] extends (...args: any[]) => any
// Functions are not allowed, use never to exclude it.
? never
// Not a function, it is data, set the value of this property to its own key.
: K
// Get the union of all values (which are now the keys that have not been set to `never`)
}[keyof T]
// Pick just the keys from the class that are ClassDataKeys.
type ClassData<T> = Pick<T, ClassDataKeys<T>>
// Works!
const test1: ClassData<SomeClass> = {
foo: 'asd',
bar: 'asd',
}
Run Code Online (Sandbox Code Playgroud)
这是一个两步过程。首先是使用映射类型和条件来测试每个属性是否是一个函数。然后收集那些不是函数的属性名称。最后,仅选择被视为类数据的属性名称。
| 归档时间: |
|
| 查看次数: |
824 次 |
| 最近记录: |