【问题标题】:Why does TypeScript not report a "wrong" function return type为什么 TypeScript 不报告“错误”的函数返回类型
【发布时间】:2021-09-29 07:33:06
【问题描述】:

我很惊讶为什么 TypeScript 4.4.3 不会报告回调函数的无效类型? 这在返回“非承诺”类型时似乎是合理的,但在返回 Promise 时,我们似乎必须等待它解决。 setCallback 期望一个返回 void 的函数,但调用返回 Promise<void> 的函数表明有一些东西要等待。

const setCallback = (cb: () => void): void => {
    cb();
};

const callback = (): Promise<void> => {
    return new Promise(resolve => {
        setTimeout(() => resolve(), 100);
    });
}

setCallback(callback);

TS Playground

【问题讨论】:

标签: typescript


【解决方案1】:

TypeScript 不在乎

您只需向setCallback() 提供一个函数引用,它可以是您喜欢的任何东西。只要您不调用函数本身,它就会被视为 object 并且 TypeScript 不会给您 TypeError,因为您的 函数需要 object.

如果您要调用 object,它将变成它的相应类型,TypeScript 会在不匹配的情况下为您提供 TypeError。

  1. 通过引用传递的变量

在传递引​​用中,通过直接传递变量的引用/地址作为参数来调用函数。更改函数内部的参数会影响从函数外部传递的变量。在 Javascript 中,对象和数组是通过引用传递的。

  1. 函数 (MDN)

一般来说,函数是一个“子程序”,可以由函数外部(或在递归的情况下为内部)的代码调用。与程序本身一样,函数由称为函数体的语句序列组成。值可以传递给函数,函数会返回一个值。

在 JavaScript 中,函数是一等对象,因为它们可以像任何其他对象一样具有属性和方法。它们与其他对象的区别在于可以调用函数。简而言之,它们是 Function 对象。

示例 1

由于我不能在 void 函数上使用 .then(),我必须创建一个 IIFE 以使其成为 async,即使我期待一个 void 类型的回调它仍然有效。

const setCallback = (cb: () => void): void => {
    (async () => await cb())().then(() => console.log("Hi"));
};

const callback = (): Promise<number> => {
    return new Promise(resolve => {
        setTimeout(() => resolve(0), 100);
    });
}

setCallback(callback);

示例 2

如果您尝试使用 Promise 返回类型调用它:

“Promise”类型的参数不能分配给“() => void”类型的参数。 类型 'Promise' 与签名 '(): void' 不匹配。

错误是指Function signatures不匹配。

const setCallback = (cb: () => void): void => {
    (async () => await cb())().then(() => console.log("Hi"));
};

const callback = (): Promise<number> => {
    return new Promise(resolve => {
        setTimeout(() => resolve(0), 100);
    });
}

setCallback(callback());

【讨论】:

    猜你喜欢
    • 2020-10-02
    • 2021-05-09
    • 2019-08-21
    • 1970-01-01
    • 2021-07-16
    • 1970-01-01
    • 2021-07-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多