ts 如何判断返回是不是promise

type test = (value:object) => object|Promise<object>
const test = obj => $.Deferred().resolve(obj);
const result = test({});
// 我要在这里判断是promise类型  
// result instanceof Promise 这种没法识别自己用Promise A+实现的。如$.Deferred
if (result && result.then) {
    //业务逻辑
} else {
}
阅读 13.5k
6 个回答

TypeScript 本身提供了 PromiseLike<T> 类型。另外,TypeScript 语法中有类型断言函数语法。

如果只是想在 TPromiseLike<T> 之间进行判断:

function isPromiseLike<T>(it: T | PromiseLike<T>): it is PromiseLike<T> {
    return it instanceof Promise || typeof (it as any)?.then === "function";
}

如果是判断任意类型是不是 PromiseLike,那么只需要把参数类型改为 unknown 就可以了。

function isPromiseLike<T>(it: unknown): it is PromiseLike<T> {
    return it instanceof Promise || typeof (it as any)?.then === "function";
}

使用的时候,如果不带类型,resolve 数据的类型是 unknown。如果带了类型,就直接给你识别成那个类型了,比如

image.png

Promise 的判断,不止社区有困惑,在官方也是个难题。
没有完美的解决方案。要么为了安全性统一用 Promise;要么为了便利性用鸭子类型,检查 .then 是否存在。

if (res instanceof Promise) {
    // todo
}

type Test = <T = string>(value: T) => T | Promise<T>

result类型可能是 string,可能是 Promise<string>,if判断写得有点问题,可以直接通过 typeof 关键字排除 string 类型,那其他的一定就是 Promise 了。

if (typeof result === 'string') {
} else {
    // result 为 Promise 类型
}

type Test = (value:string) => string|Promise<string>

const test:Test = (name) => {
    return Promise.resolve(name)
}

const result = test('100');
// 这里result.then 会提示我报错。要怎么呢。 别人返回的可能是一个jq的then呀
if(typeof result === 'string'){

}else {
    result.then
}

看你的评论 是想做 函数重载 效果啊,单纯 TS 没办法实现,必须通过 参数类型 进行区别

import { typeNarrowed } from 'ts-type-predicates';

let test: (value: string) => string | Promise<string>

const result = test('1');

if (typeNarrowed<PromiseLike<string>>(result, (result) =>
{
    return result instanceof Promise || typeof result.then === 'function'
}))
{

    result.then
}
else
{
    // @ts-expect-error
    result.then
}
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题