TypeScript基礎入門之Javascript檔案型別檢查(一)
TypeScript 2.3及更高版本支援使用--checkJs在.js檔案中進行型別檢查和報告錯誤。
您可以通過新增//@ts-nocheck註釋來跳過檢查某些檔案; 相反,您可以通過在不設定--checkJs的情況下向其新增//@ts-check註釋來選擇僅檢查幾個.js檔案。 您還可以通過在前一行新增//@ts-ignore來忽略特定行上的錯誤。 請注意,如果你有一個tsconfig.json,JS檢查將遵循嚴格的標誌,如noImplicitAny,strictNullChecks等。但是,由於JS檢查相對鬆散,將嚴格的標誌與它結合可能會令人驚訝。
以下是.js檔案中檢查與.ts檔案相比如何工作的一些顯著差異:
JSDoc型別用於型別資訊
在.js檔案中,通常可以像.ts檔案一樣推斷型別。 同樣,當無法推斷型別時,可以使用JSDoc指定它們,就像在.ts檔案中使用型別註釋一樣。 就像Typescript一樣, --noImplicitAny會給你編譯器無法推斷型別的地方的錯誤。 (開放式物件文字除外;有關詳細資訊,請參見下文。) 裝飾宣告的JSDoc註釋將用於設定該宣告的型別。 例如:
/** @type {number} */ var x; x = 0;// OK x = false;// Error: boolean is not assignable to number
您可以在JavaScript文件中的JSDoc支援中找到受支援的JSDoc模式的完整列表。
屬性是從類體中的賦值推斷出來的
ES2015沒有在類上宣告屬性的方法。 屬性是動態分配的,就像物件文字一樣。
在.js檔案中,編譯器從類主體內的屬性賦值中推斷屬性。 屬性的型別是建構函式中給出的型別,除非它沒有在那裡定義,或者建構函式中的型別是undefined或null。 在這種情況下,型別是這些賦值中所有右側值的型別的並集。 始終假定建構函式中定義的屬性存在,而僅在方法,getter或setter中定義的屬性被視為可選。
class C { constructor() { this.constructorOnly = 0 this.constructorUnknown = undefined } method() { this.constructorOnly = false // error, constructorOnly is a number this.constructorUnknown = "plunkbat" // ok, constructorUnknown is string | undefined this.methodOnly = 'ok'// ok, but y could also be undefined } method2() { this.methodOnly = true// also, ok, y's type is string | boolean | undefined } }
如果從未在類體中設定屬性,則將它們視為未知。 如果您的類具有僅從中讀取的屬性,請使用JSDoc在建構函式中新增然後註釋宣告以指定型別。 如果稍後將初始化,您甚至不必提供值:
class C { constructor() { /** @type {number | undefined} */ this.prop = undefined; /** @type {number | undefined} */ this.count; } } let c = new C(); c.prop = 0;// OK c.count = "string";// Error: string is not assignable to number|undefined
建構函式等同於類
在ES2015之前,Javascript使用建構函式而不是類。 編譯器支援此模式,並將建構函式理解為與ES2015類等效。 上述屬性推理規則的工作方式完全相同。
function C() { this.constructorOnly = 0 this.constructorUnknown = undefined } C.prototype.method = function() { this.constructorOnly = false // error this.constructorUnknown = "plunkbat" // OK, the type is string | undefined }
支援CommonJS模組
在.js檔案中,Typescript瞭解CommonJS模組格式。 對exports和module.exports的賦值被識別為匯出宣告。 同樣,require函式呼叫被識別為模組匯入。 例如:
// same as `import module "fs"` const fs = require("fs"); // same as `export function readFile` module.exports.readFile = function(f) { return fs.readFileSync(f); }
Javascript中的模組支援比Typescript的模組支援更具語法上的寬容。 支援大多數分配和宣告組合。
類,函式和物件文字是名稱空間類是.js檔案中的名稱空間。 這可以用於巢狀類,例如:
class C { } C.D = class { }
並且,對於ES2015之前的程式碼,它可以用於模擬靜態方法:
function Outer() { this.y = 2 } Outer.Inner = function() { this.yy = 2 }
它還可以用於建立簡單的名稱空間:
var ns = {} ns.C = class { } ns.func = function() { }
// IIFE var ns = (function (n) { return n || {}; })(); ns.CONST = 1 // defaulting to global var assign = assign || function() { // code goes here } assign.extra = 1
未完待續...