typescript - 在 typescript 中,有没有办法确保函数的返回类型是详尽无遗的?

标签 typescript

如果你有一个像这样的常量枚举

enum Color {
  RED,
  GREEN,
  BLUE,
}

你可以写一个助手和一个 switch 语句,

function assertNever(x: never): never {
    throw new Error(`Unexpected object: ${x}`)
}

function toString (key: Color): string {
  switch (key) {
    case Color.RED: return 'Red'
    case Color.GREEN: return 'Green'
    case Color.BLUE: return 'Blue'
    default: return assertNever(key)
  }
}

如果我们改变Color,我们必须改变我们的toString实现。

但是,如果我走另一条路,

function fromString (key: string): Color {
  switch (key) {
    case 'Red': return Color.RED
    case 'Green': return Color.GREEN
    case 'Blue': return Color.BLUE
    default: throw new Error(`${key} is not a Color`)
  }
}

我的 fromString 实现可能会与我的 Color 枚举过时。

有没有办法确保存在返回每种Color 的路径?有没有办法确保函数的范围是Color

最佳答案

没有内置功能可以自动为您强制执行此操作。函数的实际返回类型比声明的返回类型更具体不会被认为是错误...如果函数被声明为返回 string 但实际上总是返回特定的字符串 “你好”,没关系。如果相反,函数被声明为返回特定字符串 "hello" 但实际上返回的是一般 string,这只是一个错误。

一般来说,要实现这样的目标,您可以做的一件事是让 TypeScript 推断函数的返回类型,然后使用编译时检查来确保它是您认为的那样。例如:

// MutuallyExtends<T, U> only compiles if T extends U and U extends T
type MutuallyExtends<T extends U, U extends V, V=T> = true;

// note how the return type is not annotated
function fromString(key: string) {
  switch (key) {
    case 'Red': return Color.RED
    case 'Green': return Color.GREEN
    case 'Blue': return Color.BLUE
    default: throw new Error(`${key} is not a Color`)
  }
  // the next line will error if not exhaustive:
  type Exhaustive = MutuallyExtends<ReturnType<typeof fromString>, Color>
}

上面的代码可以编译,但是下面的代码会因为缺少 Color.BLUE 而产生错误:

function fromString(key: string) {
  switch (key) {
    case 'Red': return Color.RED
    case 'Green': return Color.GREEN
    default: throw new Error(`${key} is not a Color`)
  }
  type Exhaustive = MutuallyExtends<ReturnType<typeof fromString>, Color> // error!
//  Color does not satisfy constraint Color.RED | Color.GREEN ---> ~~~~~
}

当然,这是一种解决方法。但也许它会对你或其他人有所帮助。希望有用;祝你好运!

关于typescript - 在 typescript 中,有没有办法确保函数的返回类型是详尽无遗的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54381572/

相关文章:

typescript - 在 VS Code 中隐藏 .js 和 .map 文件

简单 Aurelia ASP.Net 5.0 RC1 设置中的 Javascript 错误

angular - RxJs6:OperatorFunction 与 MonoTypeOperatorFunction

typescript - 如何根据条件返回属性类型?

angular - 具有相同父布局 Angular 功能模块路由

javascript - 如何有条件地在 Angular Reactive Form 中设置 [disabled] 属性值?

angular 2 HostListener - 按键空间事件在 IE 中不起作用

angular - 将验证器添加到响应式表单时出错

typescript - 推断函数的参数列表

angularjs - Angular 指令未填充 ui-sref