函数的打字稿条件返回类型

时间:2021-07-06 19:57:47

标签: typescript typescript-typings typescript-generics

我有一个可以返回两种类型的函数,如下所示:

docker network connect [OPTIONS] NETWORK CONTAINER

如果使用包含可选 function doSomething(obj: {a: string, b?: string}): string | number { if (obj.b) { return 'something' } return 1 } 属性的对象调用该函数,它将始终返回一种类型,在这种情况下,我们假设为 b

如果使用不包含可选属性 string 的对象调用该函数,它将始终返回另一种类型,在这种情况下假设为 b

目前,如果我调用该函数,返回类型将始终是 numberstring 的并集:

number

有没有办法让函数根据提供给函数的参数返回正确的类型?

const result = doSomething({a: 'a', b: 'b'})
//      ^ string | number
// although we know it is always going to be a string if the `b` property is given

我一直在尝试使用 conditional types 但没有成功,也不知道我的方向是否正确:

const result1 = doSomething({a: 'a', b: 'b'})
//      ^ string

const result2 = doSomething({a: 'a'})
//      ^ number

还尝试让 TypeScript 推断类型,但结果仍然是联合类型:

type ConditionalType<T> = T extends { b: string} ? string : number
type Argument = {
  a: string,
  b?: string,
}

function doSomething<T extends Argument>(obj: T): ConditionalType<T> {
  if (obj.b) {
    return 'something' // type string is not assignable to ConditionalType<T>
  }
  return 1 // type number is not assignable to ConditionalType<T>
}

const result = doSomething({a: 'a', b: 'b'})

TypeScript Playground

1 个答案:

答案 0 :(得分:2)

这似乎有效。这是纯函数重载:

function doSomething(obj: {a:string,b?:string}): string;
function doSomething(obj: {a:string,b?:undefined}): number;
function doSomething(obj: {a:string,b?:string}): string|number {
  if (obj.b) {
    return 'something'
  }
  return 1
}

const result1 = doSomething({a: 'a', b: 'b'})
//      ^ "something" | 1
console.log(result1);

const result2 = doSomething({a: 'a'})
//      ^ "something" | 1
console.log(result2);

TS Playground