在泛型接口中推断变量类型

Posted

技术标签:

【中文标题】在泛型接口中推断变量类型【英文标题】:Infer variable type in generic interface 【发布时间】:2021-08-14 01:17:29 【问题描述】:

我有下面的例子。

enum Foo 
    bar,
    baz


interface IBar 
    qux: number


interface IBaz 
    quux: string


type InterfaceType<T> = 
    T extends Foo.bar ? IBar :
    T extends Foo.baz ? IBaz : never;
    
interface ICorge<T> 
    foo: T
    attributes: InterfaceType<T>


const grault: Array<ICorge<unknown>> = [
    
        foo: Foo.bar,
        attributes: 
            qux: 404
        
    , 
        foo: Foo.baz,
        attributes: 
            quux: "not found"
        
       
]

我希望从foo 的类型自动推断出我的接口ICorge 的类型。有没有办法在打字稿中正确地做到这一点?

【问题讨论】:

【参考方案1】:

编辑:抱歉,我把 | 搞错了。

只要做:

const grault: Array<ICorge<Foo.bar> | ICorge<Foo.baz>> = [
    
        foo: Foo.bar,
        attributes: 
            qux: 404
        
    , 
        foo: Foo.baz,
        attributes: 
            quux: "not found"
        
       
]

查看TS playground

【讨论】:

这太简单了,我发现 typescript 泛型越多,我就越喜欢它们。谢谢。【参考方案2】:

相当有类型的仪式。更实用的类型解决方案:

interface IBar 
    foo: 'bar'
    attributes: 
      qux: number
    


interface IBaz 
    foo: 'baz'
    attributes: 
      quux: string
    


const grault: (IBar | IBaz)[] = [
    
        foo: 'bar',
        attributes: 
            qux: 44
        
    , 
        foo: 'baz',
        attributes: 
            quux: "not found"
        
       
]

TS playground

除非绝对必要,否则至少我强烈建议不要在生产代码中使用enums

【讨论】:

这只是一个来自更复杂问题的简单示例,使用您的解决方案会增加很多重复。但出于好奇,你为什么要反对enums 它们创建了大量额外的代码,并且在过度使用时可能会显着降低性能。如果您喜欢enums,我会假设使用const enum 作为一个很好的权衡。 无论如何。 InterfaceType 看起来很重。您可以使用简单的映射类型获得相同的结果:tsplay.dev/mbkRbW。或使用枚举:tsplay.dev/mA7EXw

以上是关于在泛型接口中推断变量类型的主要内容,如果未能解决你的问题,请参考以下文章

来自接口实现的 Typescript 泛型推断

JAVA泛型知识点

Java中的泛型理解

c#中关于协变性和逆变性(又叫抗变)详解

201671010114 2016-2017-2 《Java程序设计》第十周学习总结

013.泛型窗体常用属性