简体   繁体   中英

How can I correctly-type a function that returns a class in TypeScript?

In TypeScript, class keyword introduces both a value and a type:

class Plain { };
const plain: Plain = new Plain();

Is there a way to make a function that returns something that is both a type and a value?

Another way of asking this question is: is there a way to declare the type of createClass below so that const a2: Animal = new Animal() type-checks?

declare function createClass<T extends string>(t: T): (new () => { type: T });

const Animal = createClass("animal");

const a1         = new Animal();
const a2: Animal = new Animal(); // Error: 'Animal' refers to a value, but is being used as a type here.
const a3: InstanceType<typeof Animal> = new Animal(); // OK but verbose, even if I make a type alias

See this TypeScript Playground

A class declaration produces both a type and a value. The value is the constructor of the class (this is why when you write new Plain() in expressions you invoke the constructor). The type, has the same name as the class and represents the instance type of the class (this is why you can use it in type annotations)

A const on the other hand is just a value, even if it does hold a class. There is no corresponding type. The only way you can achieve a similar functionality to the class declaration is to create a type alias with the same name.

declare function createClass<T extends string>(t: T): (new () => { type: T });

const Animal = createClass("animal");
type Animal = InstanceType<typeof Animal>

const a1         = new Animal(); 
const a2: Animal = new Animal(); 

The value an the type reside in different domains, so using the same name is fine.

Unfortunately, there is no way to do this in a single statement, there is a bit of verbosity involved.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM