如何创建一个类型来返回和排除类的对象



给定以下条件:

class MyClass {}
class MyOtherClass { something!: number; }
type HasClasses = {
foo: MyClass;
bar: string;
doo: MyClass;
coo: {x: string;};
boo: MyOtherClass;
};
type RemovedClasses = RemoveClassTypes<HasClasses>;

我希望RemovedClasses等于{ bar: string; coo: {x: string;} }。我该怎么做?

我尝试过我认为有效的方法,但由于某种原因没有成功:

type ClassesKeys<T> = {
[P in keyof T]: T[P] extends new () => any ? P : never;
}[keyof T]
type RemoveClassTypes<T> = Omit<T, ClassesKeys<T>>;

您是说要根据属性是否与类相关来从类型中删除属性,而保留非class对象类型。这就是为什么在您的示例中要删除foodoo(均为MyClass(和boo(MyOtherClass(,而不是coo({x: string;}(。

我认为你做不到。

TypeScript的类型系统是结构化的(基于事物的形状(,而不是标称的状

例如,看看这个:

class Example {
something: string;
constructor(s: string) {
this.something = s;
}
method(): void {
}
}
let ex1 = new Example("ex1");
let ex2 = {
something: "ex2",
method(): void {
}
};

从类型的角度来看,ex1ex2之间没有区别,尽管在运行时的角度来看有一个微小的区别(ex1继承了它的method,而ex2将它作为自己的属性(。

现在假设您有以下声明:

let ex3: Example;
let ex4: { something: string; method(): void; };

所有这些分配都是有效的:

ex3 = ex1;  // Works
ex3 = ex2;  // Works
ex4 = ex1;  // Works
ex4 = ex2;  // Works
ex1 = ex4;  // Works
ex2 = ex4;  // Works

这些东西的类型都是兼容的。通过class构造声明的实例类型Example、从ex2的对象初始值设定项推断的类型以及分配给ex4的内联类型,它们都是相互兼容的。

一个转移注意力的问题是类中的对象具有继承的constructor属性,也许我们可以使用它!但你不能,因为即使是上面的ex2也有一个继承的constructor属性(来自Object.prototype.constructor,即Object(,而且我认为TypeScript对constructor属性的处理有点特殊(但不能指向任何文档,可能会出错(。

所以恐怕我不认为你能做你说过你想做的事。