Reputation: 362
I have the following code:
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; }'.
}
}
The following code works the way I want:
function b(c: MyClassType) {
if (c.state === 1) {
c.data.p2; // works fine
}
}
The following code gives me an error: 'MyClass' refers to a value, but is being used as a type here. Did you mean 'typeof MyClass'?
function c(c: MyClass) {
}
Is there a way to combine behavior of MyClassType
and MyClassImplementation
? I want to have right suggestions and create new instances using single entity (MyClass
)? So I don't want to export MyClassType
and MyClassImplementation
, only MyClass
.
Upvotes: 1
Views: 51
Reputation: 328067
My suggestion would be to rename MyClassType
to MyClass
and export
that as well as your MyClass
value:
export type MyClass = { /* your union of things */ }
export const MyClass = MyClassImplementation as {
new(): MyClass;
}
This will allow those who import MyClass
to get both the named constructor value and the named instance type, similarly to how class
names and types work:
import { MyClass } from 'mymodule';
const c: MyClass = new MyClass(); // okay
Upvotes: 2