打字稿对象包装,打字和泛型

时间:2017-04-19 20:55:41

标签: typescript interface wrapper typescript-typings proxy-classes

这有点是我昨天在其他地方发布的问题的转变。

我的目标不是获得一个工作结果,而是要更好地理解我在返回正确类型时可以获得的设计类型。这是一个极简主义的例子,所以请不要告诉我它没用或什么都不做。

代码示例(Try it in Typescript playground):

interface TestInterface { 
    test: () => {}
}

class Obj implements TestInterface{
    test() { 
        return { test: 'test' }
    }
}

class Wrapper<T extends  TestInterface> {   
    constructor(public obj: T) {
    }

    test<T>() { 
        return this.obj.test();
    }

    test2<T extends TestInterface>(obj: T) { 
        return obj.test();
    }
}

let w = new Wrapper(new Obj());
let r1 = w.obj.test();
let r2 = w.test();
let r3 = w.test2(new Obj);

下面:
w的类型为Wrapper<Obj> r1的类型为{test: string} w.test的类型为Wrapper<Obj>.test: () => {} r2的类型为{} r3的类型为{}

此案例是一个将对象存储在属性中的类。它代理对此对象的调用。

我感兴趣的是r2的返回类型。特别是我希望找到一种方法来返回与r1相同的类型而不指定三个底行中的类型。 r3是另一个测试,通过直接传递泛型类型。结果是一样的。

我对此有一些疑问:

  • 根据我的理解,Wrapper.test返回类型在OBJ泛型有任何影响之前得到解决。所以使用它的基值(在这种情况下{}TestInterface.Test的结果)。是不是?
  • 是否有目的地完成了某些工作,某些限制,未来TS版本即将发布的功能? (没看到任何关于那个)
  • 主要是,如何能够转发嵌入式对象方法返回类型(或用它们组成一个新对象),考虑到在这样的代理中,应该可以插入任何尊重TestInterface的东西。并且没有在调用者的任何地方放置泛型(在底线),我知道该怎么做。

我在这篇文章中看到了一些对象构建器:https://github.com/Microsoft/TypeScript/pull/14141。也许这就是我要采取的方向。

2 个答案:

答案 0 :(得分:1)

我认为this就是你想要的:

interface TestInterface<T1,T2> { 
    test: () => T1
    test2: () => T2
}

class Obj implements TestInterface<{ test: string }, { test2: number }>{
    test() { 
        return { test: 'test' }
    }

    test2() { 
        return { test2: 2 }
    }
}

class Wrapper<T1,T2> implements TestInterface<T1,T2>  {   
    public obj :TestInterface<T1,T2>;
    constructor(obj: { new (): TestInterface<T1,T2> }) {
        this.obj = new obj();
    }

    test():T1 { 
        return this.obj.test();
    }

    test2():T2 { 
        return this.obj.test2();
    }
}

let w = new Wrapper(Obj);
let r = w.test();
let s = w.test2();

答案 1 :(得分:0)

我回答自己,因为我喜欢使用 Stackoverflow 作为我的个人笔记本。如果有人提供更好的答案,我就是买家!

  • 显然 Typescript 是一个很大的couchpotato,并不遵循类型继承。也许是出于性能原因,也许是因为类型可能会受到其他方式的影响并且不可靠,可能是因为它很棘手,可能是因为它尚未实现,可能是因为没有人要求它,因为他们不使用该模型object,或 Intellisense
  • Typescript 2.3 的文档/即将发布的功能中没有看到任何明确的内容。在使用this编译选项和--noImplicitThis函数明确声明ThisType<T>时,会提到强烈输入this here。但显然它更多的是一个函数意识到它的嵌入结构类型,而不是跟随对象模型流。在我的情况下它没有用。
  • 那,我可以回答!

以下是代码示例(Test it in Typescript playground):

interface TestInterface { 
    test: () => {}
}

class Obj implements TestInterface{
    test() { 
        return { test: 'test' }
    }
}

class Wrapper<T extends TestInterface, TEST> {   
    public obj;
    constructor(obj: { new (): T; prototype: { test: TEST } }) {
        this.obj = new obj();
    }

    test():TEST { 
        return this.obj.test();
    }
}

let w = new Wrapper(Obj);
let r = w.test();

在这种情况下,r类型为{test: string}。此解决方案包括不实例化Obj,而是让其原型推断出类型。

在搜索时,我还有一种更简单的方式来编写there(参见 update 2 )。

它提供了在使用某些动态模式时保持聪明的打字和主要代码完成的可能性。现在,它仍然可以选择完成或更智能/更清晰的设计...

此示例基于this page底部的 Typescript手册中的示例。