TypeScript支持重载字符串参数,以便在使用某些参数调用时可以正确键入返回any
的方法。
这在两个地方的规范中定义: https://github.com/Microsoft/TypeScript/blob/master/doc/spec.md#1.8 https://github.com/Microsoft/TypeScript/blob/master/doc/spec.md#3.9.2.4
然而,要使这些正常工作可能会很困难。这是一个具有通用get
的示例类。我希望在将字符串"a"
或"b"
传递给此函数时提供特定类型,而在所有其他情况下,返回类型为any
。
我包含两个专门的签名,然后提供一般签名,然后提供具有一般签名的实现。以下代码正确地报告了x
和y
的前两个分配的错误,但如果我删除了常规签名(get(name: string): any
),则会收到错误:Argument of type '"c"' is not assignable to parameter of type '"b"'.
为什么除了实施签名之外,还是一般签名要求吗?
export default class Example {
contents: any
get(name: "a"): number
get(name: "b"): string
// Why is this required???
get(name: string): any
get(name: string): any { return this.contents[name] }
}
let w = new Example()
// Expected errors
// Type 'number' is not assignable to type 'string'.
let x: string = w.get("a")
// Type 'string' is not assignable to type 'number'.
let y: number = w.get("b")
// I get an error here only if I remove the general signature before the
// implementation of get.
// Argument of type '"c"' is not assignable to parameter of type '"b"'.
let z: string[] = w.get("c")
答案 0 :(得分:2)
请注意section 6.2 of the spec, "Function overloads"
的最后一行请注意,实际函数实现的签名不包含在类型中。
这是有道理的,因为实现的签名需要匹配所有可能的签名,如果它包含在最终签名中,这可能会导致比我们实际想要的更一般的签名。例如:
function foo(type: "number", arg: number)
function foo(type: "string", arg: string)
function foo(type: "number" | "string", arg: number | string) {
// impl here
}
由于之前的签名,实施的签名是必要的,但如果它包含在最终签名中,则允许以下内容,尽管这正是我们想要阻止的:
foo("number", "string param")