【问题标题】:Why is the union type of two interfaces which extend a generic interface not applicable to that generic interface?为什么扩展泛型接口的两个接口的联合类型不适用于该泛型接口?
【发布时间】:2023-02-21 18:33:14
【问题描述】:

我有一个简单的通用接口 W 和两个接口 TN 扩展 W 并添加一个属性 type 可以在标记联合中使用:

interface W<V> {
    value: V
}

interface T extends W<string> {
    type: 'text'
}

interface N extends W<number> {
    type: 'number'
}

此外,我有一个类型 D,它是 TN 的联合,还有一个函数 getValue,它需要一个符合通用包装器类型的参数,并简单地返回它的包装值。

type D = T | N

const getValue = <V extends any>(
  wrapper: W<V>
): V => {
    return wrapper.value
}

我的问题是,如果我创建一个类型为D 的值并将其传递给getValue,tsc 会抱怨the argument of type 'D' is not assignable to parameter of type 'W&lt;string&gt;'

// typecast necessary because otherwise tsc would determine that d is of type 'T' which is what i don't want
const d: D = { value: 'hallo', type: 'text'} as D

// why is 'D' not an acceptable type for getValue??? Shouldn't the inferred return type simply be 'string | number'?
getValue(d)

我尝试以这样的方式键入函数getValue,如果传入类型为D的值,tsc 将能够推断返回类型将为string | number。如果我传递值 d,我希望编译器不会抱怨并推断返回类型将是 string | number

【问题讨论】:

    标签: typescript typescript-generics


    【解决方案1】:

    您可以使用条件类型!

    interface W<V> {
        value: V
    }
    
    interface T extends W<string> {
        type: 'text'
    }
    
    interface N extends W<number> {
        type: 'number'
    }
    
    type D = T | N
    
    const getValue = <V extends W<any>>(wrapper: V): V extends W<infer U> ? U : never => {
        return wrapper.value; 
    }
    

    Playground

    【讨论】:

    • 不幸的是,这并没有解决我的实际情况,其中 tsc 无法检查 d 的实际形状,但只有 d 的类型为 D 的信息。这就是我添加类型断言的原因。
    • @Rascat 请看我的编辑!
    猜你喜欢
    • 2018-04-09
    • 1970-01-01
    • 2019-04-06
    • 2018-07-23
    • 2015-04-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-06
    • 1970-01-01
    相关资源
    最近更新 更多