2017-09-01 101 views
1

對於一個接口,可以使用Partial<X>,Mapped Type來表示「允許X的所有屬性,但是不要期望它們」。是否有TypeScript'Partial <any>`類型的函數參數接受`any`,但是`void`?

,這樣下會導致編譯器錯誤:

interface X { foo: boolean } 

function doSomething(x: Partial<X>) { 
    let aBoolean: boolean = x.foo; // ERROR: possibly undefined 
} 

doSomething({ foo: true }); // OK 
doSomething({}); // OK 
doSomething(true); // ERROR: Type 'boolean' has no properties in common with 'Partial<X>' 

我願做同樣的事情any說「這個功能可以接受任何作爲參數,但你不能指望什麼在那裏」

function doSomething(x: Partial<any>) { 
    let aBoolean: boolean = x.foo; // OK, but I wish it wasn't 
} 

doSomething({ foo: true }); // OK 
doSomething({}); // OK 
doSomething(true); // OK 
doSomething(/* etc. */); // OK 

我想我的函數接受任何和一切作爲參數,但裏面的功能我不應該能夠在對象上訪問任何屬性,而不首先檢查他們。如果功能x的類型爲voidnever,則甚至可以。

我並不感到驚訝Partial<any>並不像我希望的工作 - 我絕對不「爲什麼不Partial<any>的工作,我希望它做的方式。」我問:

我可以使用參數什麼類型x這樣:

  1. 它接受的任何參數/每一種類型的
  2. 在函數內部的x類型是一些地方每個屬性是可能未定義(或xvoid類型等)
+0

只需要'x'可選? [TS playground](https://www.typescriptlang.org/play/#src=const%20act%20%3D%20(x%3F%3A%20Partial%3Cany%3E)%20%3D%3E%20 !! x.foo%3B%0D 0A%%0D%0Aact(%7B%20foo%3A%20true%20%7D)%3B%20%2F%2F%20OK%0D%0Aact(%7B%7D)%圖3B%20%2F%2F%20OK%0D%0Aact(真)%3B%20%2F%2F%20OK%0D%0Aact(%2F *%20etc。%20 *%2F)%3B%20%2F% 2F%20OK) –

+0

在這個例子中執行'!! x.foo'時沒有錯誤 - 或者如果將其改爲'{let bar:string = x.foo; }'。我錯過了什麼嗎? – alexanderbird

+0

關鍵是在函數內部不能保證'x'具有什麼屬性,我希望類型能夠反映這一點。 – alexanderbird

回答

1

What type can I use for the parameter x such that:

1. it accepts arguments of any/every type 
2. inside the function the type of x is something where every property 
    is possibly undefined (or x is of type void, etc.) 

它是空的對象類型{},這與幾乎任何類型的兼容,並允許您通過幾乎任何東西doSomething

function doSomething(x?: {}) {...} 

doSomething({ foo: true }); // OK 
doSomething({}); // OK 
doSomething(true); // OK 
doSomething(/* etc. */); // OK 

但沒有在執行有人知道它,沒有你不能使用它先檢查:

function doSomething(x?: {}) { 
    //let b: boolean = x; // error 
    //let o: {} = x; // error when strictNullChecks in on 
    //let bar: string = x.foo; // error 

    if (typeof x === 'boolean') { 
     let b: boolean = x; 
    } 
    if (x !== undefined) { 
     if (hasProperty(ofTypeString, x, 'foo')) { 
      let bar: string = x.foo; 
     } 
    } 
}; 

function hasProperty<T, N extends string>(
    guard: (p: any) => p is T, 
    x: {}, 
    name: N 
): x is {[n in N]: T} 
{ 
    return (name in x) && guard((x as any)[name]); 
} 


function ofTypeString(p: any): p is string { 
    return typeof p === 'string' 
} 
相關問題