2017-08-02 55 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") 
相關問題