【问题标题】:Typescript infer Generic types from ImplementationTypescript 从实现中推断通用类型
【发布时间】:2019-04-24 21:18:41
【问题描述】:

所以我正在开发一个 react-native 项目。 我希望能从实现中推断出通用类型。

type itemType<T> = { item: T };

const someItem = {
    item: 'Some String'
};

type someItemType = typeof someItem;
// So Here someItemType will be {item: string}, i want it to be itemType<string> and 
// in this example i have implemented itemType but in real use case i want to infer 
//it from the actual implementation  

【问题讨论】:

    标签: typescript typescript-typings


    【解决方案1】:

    目前 typescript 不支持对变量的部分推断。您唯一的选择是使用函数的推理行为:

    type itemType<T> = { item: T };
    const createItemType = <T>(o: itemType<T>) => o;
    
    const someItem = createItemType({ //someItem is typed as itemType<string>
        item: 'Some String'
    })
    

    请注意,在您的原始示例中,someItem 键入为{item: string}, 可能并不重要,它仍然可以分配给itemType&lt;string&gt;,因为打字稿使用结构兼容性来确定可分配性。因此,如果结构兼容,一切正常:

    type itemType<T> = { item: T };
    
    const someItem ={ 
        item: 'Some String'
    }
    const someOtherItem: itemType<string> = someItem // ok
    

    【讨论】:

    • 在这种情况下,我不会编写额外的运行时代码,因为在名义类型系统之外使名称匹配没有任何好处。
    • @Fenton 同意,这就是为什么我指出如果someItem 是什么实际类型并不重要,至少在未来可分配给itemType&lt;string&gt; 方面。确保对象符合声明站点的itemType&lt;T&gt; 接口可能会有好处,而不是对未来的使用,我希望在大多数情况下,标识函数的性能影响不会太高。
    • 众所周知,我不担心性能影响 - 我担心必须在六个月内返回并更改程序 :)
    • @Fenton 我必须承认,虽然我确实担心我已经使用这些函数来帮助推理全部在一行中 const someItem = (&lt;T&gt;(o: itemType&lt;T&gt;) =&gt; o)({ item: 'Some String' }) 我会在 6 个月内理解.. 不确定其他人是否理解他们现在:)
    • 我有一些代码在 C# 中看起来有点像这样。我认为,如果您将其闪现半秒钟并让人们猜测他们看到了什么,并且他们回答“正则表达式”,那么就该重构了。
    【解决方案2】:

    类型定义为{ item: string }itemType&lt;string&gt; 无关紧要,因为TypeScript 使用结构类型。这意味着两者是相同的,因为它们具有相同的结构。

    例如,您可以将任一类型的值分配给其他类型:

    type itemType<T> = { item: T };
    
    const someItem = {
        item: 'Some String'
    };
    
    type someItemType = typeof someItem;
    
    const a: itemType<string> = { item: 'exmaple a' };
    const b: someItemType = { item: 'exmaple b' };
    
    let c: itemType<string>;
    
    c = a;
    c = b;
    
    let d: someItemType;
    
    d = a;
    d = b;
    

    【讨论】:

    • 所以我不想写 type itemType = { item: T };我想从实现中推断出来。
    • 这样,如果我更新原始对象,我的类型会自动更新。
    • 如果更新原始对象,它可能不再是itemType&lt;T&gt;
    猜你喜欢
    • 1970-01-01
    • 2018-08-09
    • 2021-02-21
    • 2017-03-08
    • 2010-09-29
    • 2018-07-03
    • 2017-03-12
    • 2021-11-08
    相关资源
    最近更新 更多