微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

重载的Typescript签名,其后的参数类型会根据第一个参数类型进行更改

如何解决重载的Typescript签名,其后的参数类型会根据第一个参数类型进行更改

我认为有可能使用打字稿重载函数类型签名来表达一种情况,即当第一参数类型更改时,第三参数类型更改。

type ActionAsync<S> = {
  (order: boolean,seek: S,limit: number): Promise<number>
  (order: null,seekAfter: S,seekBefore: S): Promise<number>
};

async function foo() {
    return 5
}

const x: ActionAsync<Date> = async (order: boolean|null,seekOrSeekAfter: Date,limitOrSeekBefore: number | Date) => {
    if (order === null) {
        return foo();
    }
    if (order === true) {
        return limitOrSeekBefore + 43;
    } else if (order === false) {
        return foo();
    }
}

您可以看到,如果limitOrSeekBeforenumberorder应该是boolean,但是当{{时,应该是SDate 1}}是order

但是,这不会进行类型检查。只有当我更改为null时,它才会生效。

解决方法

如果“不进行类型检查”是指编译器不了解order === true意味着limitOrSeekBeforenumber,那么这只是设计限制在TypeScript中。如果将箭头函数分配给具有多个调用签名的变量,则编译器不会对实现中的每个调用签名执行控制流分析。它只是根据实现签名进行一次遍历,并且由于orderlimitOrSeekBefore是那里不相关的联合类型,因此编译器无法为您进行任何验证。

典型的问题是microsoft/TypeScript#38622,其中的技术领先者是

检测到这是有效分配的唯一方法是读取函数主体并了解它在每种重载情况下的行为都正确;这样做远远超出了TS的能力。

请注意,在您的情况下,“正常”重载也会发生相同的问题:

async function y(order: boolean,seek: Date,limit: number): Promise<number>;
async function y(order: null,seekAfter: Date,seekBefore: Date): Promise<number>;
async function y(order: boolean | null,seekOrSeekAfter: Date,limitOrSeekBefore: number | Date) {
  if (order === null) {
    return foo();
  }
  if (order === true) {
    return limitOrSeekBefore + 43; // error
  } else {
    return foo();
  }
}

编译器仅基于实现签名(而不是调用签名)进行控制流分析。正常的重载稍微宽松一些,因为您可以返回一个仅适用于某些呼叫签名的值,但是由于您的返回值在所有情况下均为Promise<number>,因此此处的行为没有区别。


为使其正常工作,我建议您使用type assertion来告诉编译器知道limitOrSeekBeforenumber,因此不应不用担心:

const x: ActionAsync<Date> = async (order: boolean | null,limitOrSeekBefore: number | Date) => {
  if (order === null) {
    return foo();
  }
  if (order === true) {
    return limitOrSeekBefore as number + 43;
  } else {
    return foo();
  }
}

Playground link to code

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?