How to use class returned by a function in type annotations?

后端 未结 2 785
你的背包
你的背包 2021-01-14 20:32

This is the simplified code

export interface MyInterface{
    // Have no idea why I need an export here.
    // If I remove it, it gives
    // semantic erro         


        
相关标签:
2条回答
  • 2021-01-14 21:23

    TL;DR

    Add a type definition for MyClass

    const MyClass = createClass();
    type MyClass = InstanceType<typeof MyClass>
    

    Explanation

    Consider the flowing simple class declaration:

    class MyClass {}
    const mc: MyClass = new MyClass() 
    

    When you declare a class with the class keyword, the compiler knows two things. That in the current scope there is a value with the name of the class that is capable of constructing the class (ie the MyClass constructor) and that a type with the same name as the class will also exist in the current scope representing the instance type for the class (in this case the MyClass type). See this answer for value space vs type space.

    Since you declare the class in a function even if you were to give it a name it would only be accessible inside the function (basic scoping rules). The interface is accessible as it is in the same scope (assuming everything is in the same file) or is explicitly imported (if you are in another module).

    When you use the returned function and assign it to a const (const MyClass = createClass();) you are only doing half of what a class declaration would do, you are telling the compiler that a constructor named MyClass exists. The compiler will add no type for the instance type of MyClass (why would it, an assignment of a const does not usually introduce new types, just new values).

    The simple solution is to do the other half of the job, add a type with the same name that will be the instance type for the returned class. The two names will not collide, as one is in value space (the const) the other in type space (the type)

    const MyClass = createClass();
    type MyClass = InstanceType<typeof MyClass>
    const mc: MyClass = new MyClass(); // Ok now.
    

    Note I am assuming you are declaring the class inside a function and returning it with a reason that is not obvious from the question, if you are not just use a class declaration instead.

    0 讨论(0)
  • 2021-01-14 21:30

    TS2451 Cannot redeclare block-scoped variable 'createClass'

    This error occurs because you have createClass function somewhere else in your ambient environment. Ambient means, not scoped by modules. Writing at least one import or export scopes your file, i.e. makes it a module. Instead of exporting random interface you could just do this: export {} in the end of the file.

    const MyClass = createClass(); 
    const mc: MyClass
    

    In the above code you are mixing types with values. Specifically, MyClass is a value here and you are trying to use it as a type.

    Overall, you are doing weird things by returning a class by a function. I know you might have your own reasons for that, but normally you should write that code like this:

    class MyClass {}
    const mc: MyClass = new MyClass() // thought the type annotation is not necessary
    
    0 讨论(0)
提交回复
热议问题