typescript 类型 T 或函数 () => T 用法

标签 typescript

您可以在 this playground 中看到演示.

我制作了一个简单的泛型类型,它可以表示一个变量或一个返回变量的函数。但是,不幸的是,它不适用于典型的 typeof arg === 'function'查看。它产生以下错误:
This expression is not callable. Not all constituents of type '(() => T) | (T & Function)' are callable. Type 'T & Function' has no call signatures.
有没有办法让它在不使用类型保护功能的情况下工作?

type Initializer<T> = T | (() => T)

function correct(arg: Initializer<string>) {
    return typeof arg === 'function' ? arg() : arg
}

function wrong<T>(arg: Initializer<T>) {
    return typeof arg === 'function' ? arg() : arg // error here
}

const isFunction = (arg: any): arg is Function => typeof arg === 'function'

function correct_2<T>(arg: Initializer<T>) {
    return isFunction(arg) ? arg() : arg
}

最佳答案

你可以写:

type Initializer<T> = T extends any ? (T | (() => T)) : never

function correct<T>(arg: Initializer<T>): T {
    return typeof arg === 'function' ? arg() : arg // works
    // arg is Initializer<T> & Function in the true branch
}

const r1 = correct(2) // const r1: 2
const r2 = correct(() => 2) // const r2: number

在原始版本中,arg已解析为 (() => T) | (T & Function)在真正的分支中。 TS 显然无法识别这种联合函数类型,即两个成分都是可调用的。至少在以上版本中,编译器很清楚您可以调用 arg功能检查后。

可能也值得 create a github issue对于 TypeScript 存储库中的这种情况 - 在我看来 T & Function应该代表某种(宽)类型的功能。

关于 typescript 类型 T 或函数 () => T 用法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60898079/

相关文章:

javascript - 在 typescript 中 trim 特殊字符之前获取输入[文本]值

javascript - md-dialog 中的 md-autocomplete 在点击时失去焦点

angularjs - Angular 指令依赖注入(inject) - TypeScript

javascript - 在 typescript 中,如何从 "lodash/merge"导入合并

reactjs - 如何使用 react-native-testing-library getByRole

javascript - 属性(property)观察员与自制设置员

javascript - ionic 2 在应该寻找 app.js 的时候却寻找 app.ts

visual-studio - Visual Studio TypeScript - 找不到模块

angular - canActivate 上结束 return 语句的问题

javascript - Yammer REST API - 使用换行符发布到 messages.json