我有以下代码:
type MyClassType = {
state: 0;
data: {
p1: boolean;
};
} | {
state: 1;
data: {
p2: boolean;
};
} | {
state: 2;
data: {
p3: boolean;
};
}
class MyClassImplementation {
state = 0;
data = {
p1: true
};
}
export const MyClass = MyClassImplementation as {
new (): MyClassType;
}
function a(c: MyClassImplementation) {
// works fine, but without completion I want
if (c.state === 1) {
c.data.p2; // error: Property 'p2' does not exist on type '{ p1: boolean; }'.
}
}
下面的代码按我想要的方式工作:
function b(c: MyClassType) {
if (c.state === 1) {
c.data.p2; // works fine
}
}
下面的代码给了我一个错误:'MyClass'引用了一个值,但在这里被用作类型。你是说"MyClass的类型"吗?
function c(c: MyClass) {
}
是否有办法将MyClassType
和MyClassImplementation
的行为结合起来?我想有正确的建议,并使用单一实体(MyClass
)创建新的实例?所以我不想导出MyClassType
和MyClassImplementation
,只导出MyClass
。
我的建议是将MyClassType
重命名为MyClass
和export
,以及您的MyClass
值:
export type MyClass = { /* your union of things */ }
export const MyClass = MyClassImplementation as {
new(): MyClass;
}
这将允许那些导入MyClass
的人同时获得命名的构造函数值和命名的实例类型,类似于class
名称和类型的工作方式:
import { MyClass } from 'mymodule';
const c: MyClass = new MyClass(); // okay
Playground链接到代码