【问题标题】:Typescript conditional return type for a funciton函数的打字稿条件返回类型
【发布时间】:2021-09-17 10:48:10
【问题描述】:

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

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

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

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

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

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

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

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

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

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

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 推断类型,但结果仍然是联合类型:

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

const result = doSomething({a: 'a', b: 'b'})
//      ^ "something" | 1

TypeScript Playground

【问题讨论】:

标签: typescript typescript-typings typescript-generics


【解决方案1】:

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

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

【讨论】:

    猜你喜欢
    • 2022-07-07
    • 2021-09-18
    • 2022-01-12
    • 1970-01-01
    • 2015-08-10
    • 1970-01-01
    • 2021-09-05
    • 2021-10-22
    • 1970-01-01
    相关资源
    最近更新 更多