当前位置: 首页 > 知识库问答 >
问题:

TypeScript:如何编写条件返回类型的函数

薛博艺
2023-03-14
export type Name = { name: string }
export type Id = { id: number }
export type Value<T> = T extends string ? Name : Id

export function create<T extends string | number>(value: T): Value<T> {
    if (typeof value === "string") return { name: value }

    return { id: value }
}

我在玩TypeScript中的条件类型。我想用条件返回类型编写一个函数。如果函数被传递一个字符串,它将返回一个名称,否则它将返回一个Id。

我在返回语句中得到以下错误:

Type '{ name: T & string; }' is not assignable to type 'Value<T>'.

我错过了什么?Thnx!

编辑:直接摘自Anders Hejlsberg在Build 2018上的演讲:https://youtu.be/hDACN-BGvI8?t=2241

他甚至说“我们不再需要写函数重载了…”

如果我将代码更改为一个声明,编译错误就会消失:

export type Name = { name: string }
export type Id = { id: number }

export type Value<T> = T extends string ? Name : Id

declare function create<T extends string | number>(value: T): Value<T>

const a = create("Bob")     // a : Name
const b = create(5)         // b : Id

所以我们可以声明函数签名。我想我的问题是,我们实际上如何实现这个功能?

共有3个答案

堵存
2023-03-14

我不确定我是否完全理解你的例子,但我认为这就是你想要的?

type Name = { name: string }
type Id = { id: number }
type Value = Name | Id

export function create(value: string | number): Value {
  if (typeof value === "string") return { name: value }
  return { id: value }
}

请看,我已经从您的示例中删除了任何泛型,因为我不认为在这种情况下需要它们

缪风史
2023-03-14

这里是另一个解决方案,它也很好用。

与公认的答案相比,我更喜欢此解决方案,因为在编码时,您将获得正确的类型推断:

悬停时可以看到,它正确地推断了类型。

以下是屏幕截图中的代码:

export type Name = { name: string }
export type Id = { id: number }
export type Value<T extends string | number> = T extends string ? Name : Id

export function create<T extends string | number>(value: T): Value<T> {
    if (typeof value === 'string') return { name: value } as unknown as Value<T>

    return { id: value } as unknown as Value<T>
}
端木权
2023-03-14

问题出在函数T内部,因此您无法真正为值赋值

export function create<T extends string | number>(value: T): Value<T> // public signature
export function create(value: string | number): Name | Id { // more relaxed private implementation signature 
    if (typeof value === "string") return { name: value }

    return { id: value }
}

 类似资料:
  • 假设我想写一个函数,它可以接受一个参数,这个参数可以是null类型,也可以是非null类型。如果参数不可为null,则返回类型也应不可为null。类似地,如果参数是可空类型,那么返回类型也应该是可空类型。 以下是我为实现这一职能所做的尝试: 函数签名似乎是正确的,因为它在调用站点上实现了所需的行为,例如: 即返回类型确实由参数类型以正确的方式确定。 然而,我的问题在于函数的实现。如果不将返回值强制

  • 我想基于泛型值返回不同的类型。例如: 但我有一个错误: 类型字符串[]不能分配给类型T扩展Base?String[]:字符串

  • 我在这里查过了https://github.com/Microsoft/TypeScript/blob/master/doc/spec.md这是TypeScript语言规范,但我找不到如何声明函数的返回类型。 我在下面的代码中展示了我所期望的: 我知道我可以用

  • (沙盒) 获取此错误: 类型“number”不可分配给类型“T”“number”可分配给“T”类型的约束,但“T”可以用约束{}的不同子类型实例化。(2322)输入。ts(1,26):预期类型来自此签名的返回类型。 我希望typescript能够自动推断T为数字,然后直接使用它。为什么它在抱怨?写这样的东西的正确方法是什么?谢谢

  • 问题内容: 例如,我要创建一个可以返回任何数字(负数,零或正数)的函数。 但是,基于某些异常,我希望函数返回 有没有一种方法可以编写可以返回 或 的函数? 好的,因此收到了很多答复。我知道我只是在错误地解决问题,因此我应该在方法中使用某种异常。为了获得更好的答案,我将提供一些示例代码。请别取笑:) 问题答案: 不,您不能在Java中做到这一点。 您可以返回一个。通过返回一个对象,您可以从技术上返回

  • 我想通过TypeScript泛型定义函数返回类型。所以R可以是我将定义的任何东西。 <代码>。。。许诺 错误:(29,9)TS2322:类型“字符串”不可分配给类型“R”。“字符串”可分配给类型“R”的约束,但“R”可以用约束“{}”的不同子类型实例化。