TypeScript基礎入門之Javascript檔案型別檢查(二)
繼續上篇文章【ofollow,noindex">TypeScript基礎入門之Javascript檔案型別檢查(一) 】
物件文字是開放式的
在.ts檔案中,初始化變數宣告的物件文字將其型別賦予宣告。不能新增未在原始文字中指定的新成員。此規則在.js檔案中放寬;物件文字具有開放式型別(索引簽名),允許新增和查詢最初未定義的屬性。例如:
var obj = { a: 1 }; obj.b = 2;// Allowed
物件文字的行為就像它們具有索引簽名[x:string]:任何允許它們被視為開放對映而不是封閉物件的任何東西。
與其他特殊的JS檢查行為一樣,可以通過為變數指定JSDoc型別來更改此行為。例如:
/** @type {{a: number}} */ var obj = { a: 1 }; obj.b = 2;// Error, type {a: number} does not have property b
null,undefined和empty陣列初始值設定項的型別為any或any[]
使用null或undefined初始化的任何變數,引數或屬性都將具有型別any,即使打開了嚴格的空檢查。使用[]初始化的任何變數,引數或屬性都將具有型別any[],即使打開了嚴格的空檢查。唯一的例外是具有如上所述的多個初始值設定項的屬性。
function Foo(i = null) { if (!i) i = 1; var j = undefined; j = 2; this.l = []; } var foo = new Foo(); foo.l.push(foo.i); foo.l.push("end");
功能引數預設是可選的
由於無法在ES2015之前的Javascript中指定引數的可選性,因此.js檔案中的所有函式引數都被視為可選引數。允許使用引數少於宣告的引數數量的呼叫。
重要的是要注意,呼叫具有太多引數的函式是錯誤的。
例如:
function bar(a, b) { console.log(a + " " + b); } bar(1);// OK, second argument considered optional bar(1, 2); bar(1, 2, 3); // Error, too many arguments
JSDoc註釋函式被排除在此規則之外。使用JSDoc可選引數語法來表示可選性。例如:
/** * @param {string} [somebody] - Somebody's name. */ function sayHello(somebody) { if (!somebody) { somebody = 'John Doe'; } console.log('Hello ' + somebody); } sayHello();
由arguments推斷出的var-args引數宣告
其主體具有對引數引用的引用的函式被隱式地認為具有var-arg引數(即(...arg: any[]) => any)。使用JSDoc var-arg語法指定引數的型別。
/** @param {...number} args */ function sum(/* numbers */) { var total = 0 for (var i = 0; i < arguments.length; i++) { total += arguments[i] } return total }
未指定的型別引數預設為any
由於在Javascript中沒有用於指定泛型型別引數的自然語法,因此未指定的型別引數預設為any。
在extends子句中:
例如,React.Component被定義為具有兩個型別引數,Props和State。在.js檔案中,沒有合法的方法在extends子句中指定它們。預設情況下,型別引數將是any:
import { Component } from "react"; class MyComponent extends Component { render() { this.props.b; // Allowed, since this.props is of type any } }
使用JSDoc @augments明確指定型別。例如:
import { Component } from "react"; /** * @augments {Component<{a: number}, State>} */ class MyComponent extends Component { render() { this.props.b; // Error: b does not exist on {a:number} } }
在JSDoc引用中
JSDoc中的未指定型別引數預設為any:
/** @type{Array} */ var x = []; x.push(1);// OK x.push("string"); // OK, x is of type Array<any> /** @type{Array.<number>} */ var y = []; y.push(1);// OK y.push("string"); // Error, string is not assignable to number
在函式呼叫中
對泛型函式的呼叫使用引數來推斷型別引數。有時這個過程無法推斷任何型別,主要是因為缺乏推理源;在這些情況下,型別引數將預設為any。例如:
var p = new Promise((resolve, reject) => { reject() }); p; // Promise<any>;
未完待續...