函数参数类型推断和条件类型

Function argument type inference and conditional type

我正在尝试涵盖以下案例:

我有一个函数接受布尔值和 returns RealItem | ImaginaryItem 类型的值。我正在使用条件类型来缩小基于 boolean 参数的 return 类型。

type RealItem = { color: string }
type ImaginaryItem = { description: string }

export function createItem<T extends boolean>(isReal: T): T extends true ? RealItem : ImaginaryItem

export function createItem<T extends boolean>(isReal: T): RealItem | ImaginaryItem {
  return isReal ? { color: 'red' } : { description: 'Crazy thing' }
}

我的签名似乎适用于以下情况:

const a = createItem(true)      | typeof a -> RealItem
const b = createItem(false)     | typeof b -> ImaginaryItem


let isReal = true
const a = createItem(isReal)    | typeof a -> RealItem

let isReal = false
const b = createItem(isReal)    | typeof b -> ImaginaryItem

但是,如果我将 createItem 包装到另一个函数中并传递 isReal 参数:

const itemsFactory = (isReal: boolean) => createItem(isReal)

TS 似乎无法扣除 return type narrowed with conditional return type:

const a = itemsFactory(true)    | typeof a -> RealItem | ImaginaryItem
const b = itemsFactory(false)   | typeof b -> RealItem | ImaginaryItem

TS playground

我不会说谎,工会类型让我很不高兴。

我知道我可以在这里使用类型保护,但是它们不适合我当前的代码结构。

isReal 的类型信息在 itemsFactory 函数中基本上丢失了,因为您在此处将 isReal 指定为 boolean

要解决此问题,您还可以将相同的泛型类型添加到 itemsFactory 函数:

const itemsFactory = <T extends boolean>(isReal: T) => createItem(isReal)

Playground