【问题标题】:Typescript object wrapping, typings and generics [duplicate]打字稿对象包装,打字和泛型[重复]
【发布时间】:2017-09-16 06:47:17
【问题描述】:

这在某种程度上是我昨天在其他地方发布的问题的转变。

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

代码示例(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&lt;Obj&gt;
r1的类型为{test: string}
w.test的类型为Wrapper&lt;Obj&gt;.test: () =&gt; {}
r2的类型为{}
r3 的类型为 {}

这种情况是一个在属性中存储对象的类。它代理对该对象的调用。

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

我对此有一些疑问:

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

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

【问题讨论】:

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


    【解决方案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();
    

    【讨论】:

    • 不完全,泛型可以在您的解决方案中稍微简化。最后我更喜欢传递一个实例化的对象。要结束这个问题,以避免在 Stackoverflow 上仅对 2 人感兴趣的主题重复。在这里发布最终答案:stackoverflow.com/questions/43485022/…
    • 无法删除...
    【解决方案2】:

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

    • 显然 Typescript 是一个大沙发,不遵循类型继承。也许是出于性能原因,也许是因为该类型可能会受到其他方式的影响并且不可靠,也许是因为它做起来很棘手,也许是因为它尚未实现,也许是因为没有人要求这样做,因为他们不使用该模型对象,或 智能感知
    • Typescript 2.3 的文档/即将推出的功能中没有看到任何明确的内容。在使用 --noImplicitThis 编译选项和 ThisType&lt;T&gt; 函数显式声明 this 时,提到了强类型 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 编写的更简单的方法(参见更新2)。

    当使用一些动态模式时,它提供了保持聪明的打字和主要是代码完成的可能性。现在,在完成还是更智能/更清晰的设计之间做出选择仍然是一个选择......

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

    【讨论】:

    • obj 中的每一个公共方法都会被 Wrapper 暴露出来吗?
    • 这将是一组定义的 5 个方法。所以 5 泛型类型,如果我没有找到另一种方法。也许即将到来的可变参数类型会有所帮助,不知道。
    • 我的回答对你有用吗?
    猜你喜欢
    • 2021-10-04
    • 2020-10-11
    • 2020-01-08
    • 1970-01-01
    • 2019-01-16
    • 2022-08-21
    • 2017-09-15
    • 2015-11-27
    • 1970-01-01
    相关资源
    最近更新 更多