【问题标题】: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 的类型。有没有办法在打字稿中正确地做到这一点?

【问题讨论】:

    标签: angular typescript typescript-generics


    【解决方案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
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-06
    • 1970-01-01
    相关资源
    最近更新 更多