【问题标题】:TypeScript: Is there a way to type a function so that it returns different types of results dynamically according to it paramsTypeScript:有没有办法键入一个函数,以便它根据它的参数动态返回不同类型的结果
【发布时间】:2020-11-15 14:18:31
【问题描述】:

这是一个非常人为的例子,所以请多多包涵:

我有一个函数foo。它接受一个这种类型的对象作为它的参数

interface Foo {
  bar: number,
  baz: number,
  enabled?: boolean,
}

enabled不是由用户提供或为假时,foo会返回一个Result类型的对象

interface Result {
  result: number
}

所以它只是将这两个数字相加


function foo({bar, baz}: Foo): Result {
  return {
    result: bar + baz
  }
}

问题来了:当参数中提供enabled 并将其设置为true 时,我希望该函数返回另一种类型的结果,其中有另一个字段isEqual,表示是否@987654331 @ 和 baz 是相等的。很喜欢

interface AnotherResult {
   result : number,
   isEqual: boolean
}

这是我们如何使用这个功能

const {result} = foo({baz: 1, bar: 2})

// or

const {result, isEqual} = foo({baz: 1, bar: 2, enabled: true})

理想情况下,当用户在foo 的参数中包含enabled: true 时,他们可以从foo 的返回值中解构isEqual,当他们不提供enabled 或设置enabled: false 时,他们不能foo的返回值中解构isEqual

这是我的尝试,但我想不出一种基于参数动态确定返回值类型的方法。我想知道 TypeScript 是否可以实现这一点

nterface Foo {
  bar: number,
  baz: number,
  enabled?: boolean,
}

interface Result {
  result: number
}

interface IsEqual {
  isEqual: boolean
}

type ResultWithIsEqualEnabled = Result & IsEqual


function foo({bar, baz, enabled = false}: Foo): ResultWithIsEqualEnabled {
  return {
    result: bar + baz
  }
}

【问题讨论】:

  • 我认为IsEqual接口应该继承Result接口,而不是与&操作符结合
  • 还是作文更好?不确定...

标签: javascript typescript


【解决方案1】:

你可以使用函数重载:

interface Foo {
  bar: number,
  baz: number,
}

interface FooEnabled extends Foo {
  enabled: true,
}

interface Result {
  result: number;
}

interface IsEqual extends Result {
  isEqual: boolean
}

function foo(foo: FooEnabled): IsEqual;
function foo<T extends Foo>(foo: T): Result;
function foo({bar, baz, enabled}: FooEnabled): Result | IsEqual {
  const result = baz + bar;
  
  if (enabled) {
    return {
      result,
      isEqual: bar === baz,
    }
  }

  return {
    result,
  }
}

const {result} = foo({
  bar: 5,
  baz: 5,
});

const {result: anotherOneResult, isEqual} = foo({
  bar: 5,
  baz: 5,
  enabled: true,
})

【讨论】:

    【解决方案2】:

    您可以在 typescript 中为函数定义多种返回类型。对于您的示例,您可以这样做:

        function foo({bar, baz,enabled=false}: Foo): Result | AnotherResult {
           return (enabled==true)?{result: bar + baz, isEqual: true}: {result: bar + baz} ;
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-08-01
      • 2021-01-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-03
      • 2019-10-15
      相关资源
      最近更新 更多