Typescript typings, generics and abstract classes

前端 未结 2 1873
南方客
南方客 2021-01-15 19:44

I experiment a behavior that seems strange to me.

Let\'s consider the following sample (test it in Typescript playground):

abstract class FooAbstract {         


        
2条回答
  •  萌比男神i
    2021-01-15 20:31

    Here is a clean answer and example of what is needed to pass method return types.

    the issue

    An object that embeds another object uses its internally declared type (in this case the abstract type) to determine its functions return type. Even when that object type is known (or explicitly declared).

    In other words, Typescript type inference doesn't look inside the object methods to deduce a type.

    the solution

    The only solution I found to handle that case is to associate generics to the methods/functions return types, and to match the object structure with them.

    Based on my question update 2 (test it in Typescript playground):

    interface TestInterface {
        asNum: () => ASNUM
        asString: () => ASSTRING
        asObject: () => ASOBJECT
    }
    
    interface BaseInterface extends TestInterface { }
    
    class Obj implements BaseInterface {
        constructor(private n: number) { 
        }
    
        asNum() {
            return this.n;
        }
    
        asString() {
            return this.n.toString();       
        }
    
        asObject() { 
            return {value: this.n};
        }
    }
    
    class Wrapper {
        constructor(private obj: T & TestInterface) {
        }
    
        asNum() {
            return this.obj.asNum() as ASNUM;
        }
    
        asString() {
            return this.obj.asString() as ASSTRING;
        }
    
        asObject() {
            return this.obj.asObject() as ASOBJECT;
        }
    }
    
    let w = new Wrapper(new Obj(5));
    let myNum = w.asNum();       // type: number
    let myString = w.asString(); // type: string
    let myObject = w.asObject(); // type: {value: number}
    

    The types are OK!

    alternatives

    I didn't find a lot of things about that or that could help in the docs/upcoming features of Typescript 2.3. Concerning the things that could possibly help to shape a better solution:

    • There is a post about variadic types here, maybe this could help to improve such a sample (not sure though): https://github.com/Microsoft/TypeScript/issues/5453
    • Concerning the this references, there's a mention about strongly typing this here when using the --noImplicitThis compilation option, and the ThisType function to declare this explicitely. But apparently it's more about a function being aware of its embedding structure type, than following the object model flow. And it doesn't help in my case.

提交回复
热议问题