2017-08-02 65 views
0

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

我包含两个专门的签名,然后提供一个通用签名,然后提供具有一般签名的实现。以下代码正确地报告前两个分配为xy的错误,但如果我删除了一般签名(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") 

回答

2

section 6.2 of the spec, "Function overloads"

Note that the signature of the actual function implementation is not included in the type.

最后一行这是有道理的,因为执行的签名需要符合的所有可能的签名,并且如果它被包含在最终的签名,这可能会导致到比我们实际想要的更一般的签名。例如:

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") 
相关问题