typescript 中的重载签名和实现签名

2024-05-29

我正在阅读 Typescript 手册,我很难理解为什么以下代码片段有错误消息:

function fn(x: string): void;
function fn(vo) {
  // ...
}
// Expected to be able to call with zero arguments
fn();

这是解释,但我无法理解,有人可以向我解释这里发生了什么吗?

从外部看不到实现的签名。当编写重载函数时,您应该始终在函数的实现之上有两个或多个签名。


我对此也感到非常困惑。来自一个Kotlin/Java 安卓背景知识,我不得不说 Typescript 的重载机器需要一段时间才能掌握。

首先我们需要解决如何声明overload在打字稿中

问题 1:声明重载的方式不正确[不是问题的原因]

我关于处理重载的最初想法是编写以下代码:

function makeDate(timestamp: number): void { /* code */ }
function makeDate(m: number, d: number, y: number): void { /* code */ }

我立刻就被击中了Duplicate function implementation.ts(2393)棉绒错误。一开始我很困惑,因为这就是你声明的方式overload在 Java 和 Kotlin 中。然而,这实际上不是你声明的方式overload在 Typescript 中,我相信这是问题的主要原因。

问题1的答复:

结果在 Typescript 中声明了overload不是通过使用具有相同名称和不同签名的两个方法以及各自的实现来实现。相反,它首先定义具有相同名称和不同签名但没有主体的方法,最后提供一个具有实现的方法(方法主体),该方法能够处理所有先前声明的无主体方法。

问题 2:论证的数量不正确overload要求[问题的原因]

现在我已经找到了在 Typescript 中创建重载方法的正确方法,我直接编写了以下代码:

[代码2.1]

function fn(x: string): void; // <-- Define one way to call method
function fn(x: string, y: string, z: string): void; // <-- Define another way to call method with more param (overloaded way)
function fn(x: string, y?: string, z?: string): void { // <--- provide a method with a body that can handle both previous two declarations
    if (y === undefined) {
        console.log("branch 1")
    } else {
        console.log(`branch 2 -> ${x} :: ${y} :: ${z}`)
    }
}

fn("x")
fn("xxx", "yyy", "zzz")

Outputs:

$ branch 1
$ branch 2 -> xxx :: yyy :: zzz

在上面的代码片段中,我们声明了1 method with 2不同的过载。

  1. 过载 1 ->function fn(x: string): void;
  2. 过载 2 ->function fn(x: string, y: string, z: string): void;它们都是由“具体的” method:
function fn(x: string, y?: string, z?: string): void {
    if (y === undefined) {
        console.log("branch 1")
    } else {
        console.log(`branch 2 -> ${x} :: ${y} :: ${z}`)
    }
}

由于这个方法有一个主体,这就是为什么我称它为具体方法。另请注意,此方法处理这种情况@params: x, 与@params: y and z是可选的,通过这样做它涵盖了方法调用 {overload1 and overload2}。这是一个有效的重载。

遵循同样的心态,我继续编写了以下代码:

[代码2.2]

function fn2(x: string): void;
function fn2(x: string, y: string): void;
function fn2(x: string, y?: string): void {
    if (y === undefined) {
        console.log("branch 1")
    } else {
        console.log(`branch 2 -> ${x} :: ${y}`)
    }
}

fn2("x")
fn2("x", "y")

Outputs:

$ branch 1
$ branch 2 -> x :: y

该代码也有效,正如我所怀疑的那样。所以我又写了一些代码:

[代码2.3]

function fn3(): void;
function fn3(x?: string): void {
    if (x === undefined) {
        console.log("branch 1")
    } else {
        console.log(`branch 2 -> ${x}`)
    }
}

fn3()
fn3("x")

但这一次代码不起作用并且tsc正在抱怨:

Playground.ts:219:5 - error TS2554: Expected 0 arguments, but got 1.

219 fn3("x")
        ~~~

Found 1 error.

现在我们应该花一些时间来理解文档中的引用:

从外部看不到实现的签名。当编写重载函数时,您应该始终在函数的实现之上有两个或多个签名。

我下面的理解不正确。我在这里混合犯了错误args and signature。所以下面的文字是不正确的。把它留在这里作为一个坏例子。请参阅下面@David 的回答,因为他提供了一个很好的解释来说明为什么这是不正确的。例如:下面附加的代码片段也是具有 0 ~ 1 个参数的有效重载。这可以与产生语法错误的[代码2.3]进行比较。

function fn3(): void;
function fn3(x: string): void;
function fn3(x?: string): void {
    if (x === undefined) {
        console.log("branch 1")
    } else {
        console.log(`branch 2 -> ${x}`)
    }
}

> calling:
fn3()
output:
> [LOG]: "branch 1" // correct behavior

如果你想得太多,这会很令人困惑,事实证明你可以简单地理解它“你必须有 2 个以上的参数才能进行重载”,这就是代码示例的原因[code 2.1] and [code 2.2]工作了。自从:

  • For the [code 2.1] it had 1 and 3参数。符合上述文档的要求
  • For [code 2.2] it had 1 and 2。这也符合文档中的要求。
  • 然而,对于[code 2.3] it had 0 and 1。这不符合要求您应该始终在函数的实现上方有两个或多个签名在文档中,这就是为什么tsc正在抱怨。

这实际上是有道理的,因为:

function fn3(): void;
function fn3(x?: string): void {
    if (x === undefined) {
        console.log("branch 1")
    } else {
        console.log(`branch 2 -> ${x}`)
    }
}

与仅定义一个参数相同?可选参数:

function fn3(x?: string): void {
    if (x === undefined) {
        console.log("branch 1")
    } else {
        console.log(`branch 2 -> ${x}`)
    }
}

不正确:参见@David的回答

### 对问题 2 的回答: 重载方法声明仅适用于具有 2 个和 2 个以上参数的方法,并且需要具有主体的方法来处理您为重载声明的所有情况。此外,这不适用于具有0 to 1论据,tsc会抱怨Expected 0 arguments, but got 1.ts(2554)在这种情况下。同时,声明方法的重载0 and 1参数是多余的,因为您可以使用以下方法声明一个方法1可选参数。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

typescript 中的重载签名和实现签名 的相关文章

随机推荐

  • 为 python 的 csv 阅读器中的特定行添加下标?

    我希望能够通过 csv 阅读器访问 csv 文件的特定行 例如第四行 有没有办法用 python 的 csv reader 模块来做到这一点 您只需解析所有 CSV 文件 然后使用正常的排序索引即可 否则 你可以做这样的事情 def my
  • C# 为所有对象订阅相同的事件处理程序是线程安全的吗

    我的项目中有一种情况 我连接到多个服务器并监听事件 每当从服务器接收到事件时 Handler 就应该将该事件添加到公共队列中进行处理 所有连接都应将接收到的事件添加到队列中 foreach var item in collection Co
  • 实现“LazyProperty”类 - 这是一个好主意吗?

    我经常发现自己编写的属性是惰性评估的 就像是 if backingField null backingField SomeOperation return backingField 代码不多 但如果您有很多属性 它确实会重复很多次 我正在考
  • 如何测试 Jasmine 中的值“大于或等于”?

    我想确认一个值是小数 或0 所以数字应该大于或等于零and小于 1 describe percent function it should be a decimal function var percent insights percent
  • ruby CSV重复行解析

    我有一些需要处理的 CSV 数据 但无法找到匹配重复项的方法 数据看起来有点像这样 line id name item 1 item 2 item 3 item 4 1 251 john foo foo foo foo 2 251 john
  • 如何访问 javascript 文件中的查询字符串

    可能的重复 如何获取查询字符串值 https stackoverflow com questions 901115 how can i get query string values 可以说 我们有一个
  • Flex:监听文本区域中链接上的“悬停”

    我试图找出链接何时 悬停在 显示 html 文本的文本区域中 我想知道监听光标更改类型的事件是否可能是这样 我在文档中找不到任何内容 有谁知道我可以在这里收听什么活动吗 Thanks 这是一个非常有趣的问题 根据凯的建议 我想到了一种返回A
  • 我的应用无法设置或接收来自 Firebase 的任何值,但另一个应用可以

    我最近创建了一个项目并将我的应用程序添加到其中 我已经设定了规则 Read and Write to true并尝试了一个简单的代码来向实时数据库控制台添加新值 但什么也没发生 控制台没有收到任何信息 这是我使用的代码 FirebaseDa
  • 如何更改谷歌图表标题字体大小?

    如何更改谷歌图表中标题的字体大小 var options title My Daily Activities backgroundColor transparent is3D true 在这样的选项中使用 titleTextStyle va
  • Android Studio - 程序类型已存在:org.hamcrest.CoreMatchers

    我不知道为什么会出现这个错误 Program type already present org hamcrest CoreMatchers Message kind ERROR text Program type already prese
  • 在ggplot2中创建部分虚线

    我正在 R 中创建一个图 并且需要创建一条线 其中某些值是投影 投影用虚线表示 这是代码 df data frame date c rep 2008 2013 by 1 value c 303 407 538 696 881 1094 gg
  • JWT(Json Web 令牌)与自定义令牌

    我仔细查看了问题 但没有找到任何可以解决我的疑问的内容 我找到了有关 JWT 的大量信息 但在比较 JWT 相对于针对 REST 服务生成自定义令牌来对身份验证请求提供的优势时 发现的信息并不多 与生成自定义生成令牌相比 使用 JWT Js
  • 在Python中通过套接字发送文件

    我正在尝试用 python 编写一个实现套接字的程序 每个客户端发送一个 PDF 文件 服务器接收该文件并将标题更改为 file number pdf 例如 file 1 pdf 出现的问题是只有客户端才能成功发送文件 当第二个客户端尝试发
  • SVG feColorMatrix 在 safari 中不起作用

    我有一个相当简单的设置 我想通过使用 svg 过滤器来改变 svg 图像的颜色
  • 如何在arm64主机上运行amd64 docker镜像

    警告 请求的映像平台 linux amd64 与检测到的主机平台 linux arm64 v8 不匹配 并且未请求特定平台 2021 07 28 22 25 06 349222 F tensorflow core platform cpu
  • 对象返回时是否保证被移动?

    我知道 当将对象按值传递给函数时 如果存在移动构造函数 则始终会调用移动构造函数 假设没有复制省略 按值返回对象怎么样 例如 假设我们有一堂课Foo它有一个移动构造函数 我们有一个返回一个的函数Foo object Foo g Foo f
  • 如何安装 scipy 杂项包

    我已经安装 实际上是重新安装 scipy 10 x86 64 whl 19 8MB 19 8MB downloaded Installing collected packages scipy Successfully installed s
  • URL::forceSchema 在登录前不起作用

    我在用着URL forceSchema https 在我的 Laravel 5 3 应用程序上强制使用 SSL 然而 它只有在登录后才有效 即使登录页面没有被 https 覆盖 我在用着可信代理 https github com fidel
  • 验证项目是否在开始日期和结束日期内

    我有一个java程序 它将检查每个项目的开始日期和结束日期 每个项目必须有自己特定的开始日期和结束日期范围 如果新的开始日期和结束日期的范围落在旧的开始日期和结束日期内 系统将提示错误消息 例如 Company ABC Item Numbe
  • typescript 中的重载签名和实现签名

    我正在阅读 Typescript 手册 我很难理解为什么以下代码片段有错误消息 function fn x string void function fn vo Expected to be able to call with zero a