2017-12-27 126 views
2

即使在類型斷言basarat解釋在他的大書TypeScript Deep Dive詳細差異:在打字稿type`和類型斷言`表達式作爲type`

基本上,從類型的斷言ST成功如果任STT亞型是S子類型。

我想知道是什麼類型的註釋variable: type和類型斷言expression as type之間準確的區別,更確切地說,當類型斷言是否工作,特別是關於該打字稿錯誤是一段令人吃驚:看到他們爲foo3foo5變量波紋管:

interface Foo { 
    n?: number; 
    s: string; 
} 

const foo1 = {} as Foo;    // ok 
const foo2 = { n: 1 } as Foo;   // ok 
const foo3 = { n: '' } as Foo;  // KO: "Property 's' is missing..." 
const foo4 = { n: '' as any } as Foo; // ok 
const foo5 = { n: 1, x: 2 } as Foo; // KO: "Property 's' is missing..." 
const foo6 = { s: '', x: 2 } as Foo; // ok 
const foo7 = { s: 1, x: 2 } as Foo; // KO: "Types of property 's' are incompatible." 

其他差異我注意到:在VSCode的Foo接口重命名n財產被斷言不會傳播到表情,而它的工作與類型進行批註變量。

+0

,因爲它出現了錯誤,當你提供了錯誤的類型屬性這是有趣的,但錯誤信息始終是其他的一些特性。除此之外,如果您提供的屬性名稱是正確的類型,它允許省略或添加其他屬性,這似乎是有意義的。 –

回答

2

我想知道是什麼 variable: type和類型斷言表達式類型類型註釋之間準確的區別

類型聲明variable: type告訴變量必須始終符合聲明類型的編譯器。它用於通過typechecker時的值分配給變量(該值必須與聲明的類型兼容),並且還每當使用變量(變量聲明的類型必須與任何方式的變量在使用兼容每個特定的地方)。

類型斷言覆蓋內置類型兼容性規則。它可以讓你告訴編譯器,你知道這個值實際上符合你在斷言中給出的類型,從而抑制了關於類型不兼容的錯誤信息。有限制,但是 - 你不能只是斷言,變量有你想要的任何類型的(順便說一句有any類型只是爲)。當你在問題中引用,類型斷言工作,

從類型S與T斷言成功如果任S是T的子類型或T是S

的亞型

它的工作原理正好以這種方式在各實施例:

const foo3 = { n: '' } as Foo; // KO: "Property 's' is missing..." 

這裏兩種類型:{n?: number, s: string}{n: string}被檢查兼容性 - 如果它們中的任何可以被轉換成另一種。它不能做任何一種方式:在一個方式,{n: string}缺少非可選sn有錯誤的類型(必須爲number | undefined);以另一種方式,{n?: number, s: string}有錯誤類型n(必須是string)。

完整的錯誤消息是

Type '{ n: string; }' cannot be converted to type 'Foo'. 
    Property 's' is missing in type '{ n: string; }'. 

在報告結構類型不兼容,編譯器只選擇一個不兼容的特性錯誤消息顯示 - 它可以是任何上述三個不兼容的。


const foo4 = { n: '' as any } as Foo; // ok 

作品,因爲{n?: number, s: string}{n: any}兼容:第一個可以被分配給第二 - any與任何兼容,s只是忽略(基本上,一個值與類型,如果兼容它擁有所有非可選特性與聲明的類型兼容)


const foo5 = { n: 1, x: 2 } as Foo; // KO: "Property 's' is missing..." 

{n: number, x: number}是不能分配給{n?: number, s: string} - s丟失,因爲編譯器說:

Type '{ n: number; x: number; }' cannot be converted to type 'Foo'. 
    Property 's' is missing in type '{ n: number; x: number; }'. 

const foo6 = { s: '', x: 2 } as Foo; // ok 

工作,因爲{s: string, x: number}是分配給{n?: number, s: string}s是確定的,缺少n是可以的,因爲它被聲明爲可選,額外x被忽略


const foo7 = { s: 1, x: 2 } as Foo; // KO: "Types of property 's' are incompatible." 

類型的s是不兼容的:

Type '{ s: number; x: number; }' cannot be converted to type 'Foo'. 
    Types of property 's' are incompatible. 
    Type 'number' is not comparable to type 'string'.