TypeScript泛型參數默認類型 和 新的 --strict 編譯選項


TypeScript 2.3 增加了對聲明泛型參數默認類型的支持,允許為泛型類型中的類型參數指定默認類型。

接下來看看如何通過泛型參數默認將以下react組件從 js (和jsX)遷移到 TypeScript (和TSX):

class Greeting extends react.Component { render() { return <span>Hello, {this.props.name}!</span>; } }

 

為組件類創建類型定義

咱們先從為 Component 類創建類型定義開始。每個基於類的 React 組件都有兩個屬性: props 和 state,類型定義結構大致如下:

declare namespace React { class Component { props: any; state: any; } } 

注意,這個是大大簡化的示例,因為咱們是為了演示泛型類型參數及其默認值的內容。

現在就可以通過繼承來調用上面定義的 Component:

class Greeting extends React.Component { render() { return <span>Hello, {this.props.name}!</span> } } 

咱們可以如下方式創建組件的實例:

<Greeting name="world" /> 

渲染上面組件會生成以下 html:

<span>Hello, World!</span> 

nice,繼續。

 

使用泛型類型定義 Props 和 State

雖然上面的示例編譯和運行得很好,但是咱們的 Component 類型定義不是很精確。因為咱們將 props 和 state 類型設置為 any,所以 TypeScript 編譯器也幫不上什么忙。

咱們得更具體一點,通過兩種泛型類型: Props 和 State,這樣就可以准確地描述 props 和 state 屬性的結構。

declare namespace React { class Component <Props, State> { props: Props; state: State; } } 

接着創建一個GreetingProps類型,該類型定義一個字符串類型 name 的屬性,並將其作為Props類型參數的類型參數傳遞:

type GreetingProps = { name: string }; class Greeting extends React.Component<GreetingProps, any> { render() { return <span>Hello, {this.props.name}!</span>; } } 

1) GreetingProps 是類型參數Props的類型參數

2) 類似地,any是類型參數 State 的類型參數

有了這些類型,咱們的組件得到更好的類型檢查和自動提示:

但是,現在使用 React.Component 類時就必需供兩種類型。咱們開着的初始代碼示例就不在正確地進行類型檢查:

// Error: 泛型類型 Component<Props, State> // 需要 2 個類型參數。 class Greeting extends React.Component { render() { return <span>Hello, {this.props.name}!</span>; } } 

如果咱們不想指定像GreetingProps這樣的類型,可以通過為Props和State類型參數提供any類型來修正代碼:

class Greeting extends React.Component<any, any> { render() { return <span>Hello, {this.props.name}!</span>; } } 

這種方法可以讓編譯器通過,但咱們還有更優雅的做法:泛型參數默認類型

 

泛型參數默認類型

從 TypeScript 2.3 開始,咱們可以為每個泛型類型參數添加一個默認類型。在下面的例子中,如果沒有顯式地給出類型參數,那么 Props 和 State 都都是 any 類型:

declare namespace React { class Component<Props = any, State = any> { props: Props; state: State; } } 

現在,咱們就可以不用指定泛型類型就可以通過編譯器的檢查:

class Greeting extends React.Component { render() { return <span>Hello, {this.props.name}!</span>; } } 

當然,咱們仍然可以顯式地為Props類型參數提供類型並覆蓋默認的any類型,如下所示:

type GreetingProps = { name: string }; class Greeting extends React.Component<GreetingProps, any> { render() { return <span>Hello, {this.props.name}!</span>; } } 

這兩個類型參數現在都有一個默認類型,所以它們是可選的,咱們可以僅為Props指定顯式的類型參數:

type GreetingProps = { name: string };

class Greeting extends React.Component<GreetingProps> { render() { return <span>Hello, {this.props.name}!</span>; } } 

注意,咱們只提供了一個類型參數。但是,被省略可選類型參數前一個必須要指定類型,否則不能省略。

 

其它事例

在上一篇中關於 TypeScript 2.2 中混合類的文章中,咱們最初聲明了以下兩個類型別名:

type constructor<T> = new (...args: any[]) => T; type constructable = Constructor<{}>; 

Constructable類型純粹是語法糖。它可以代替 Constructor<{}> 類型,這樣就不必每次都要寫泛型類型參數。使用泛型參數默認值,就可以完全去掉附加的可構造類型,並將{}設置為默認類型

type Constructor<T = {}> = new (...args: any[]) => T; 

語法稍微復雜一些,但是生成的代碼更簡潔,Good。

廣州VI設計公司https://www.houdianzi.com

新的 --strict 主要編譯選項

TypeScript 2.3 引入了一個新的 --strict 編譯器選項,它支持許多與更嚴格的類型檢查相關的其他編譯器選項。

TypeScript 加入的新檢查項為了避免不兼容現有項目通常都是默認關閉的。雖然避免不兼容是好事,但這個策略的一個弊端則是使配置最高類型安全越來越復雜,這么做每次 TypeScript 版本發布時都需要顯示地加入新選項。有了--strict編譯選項,就可以選擇最高級別的類型安全(了解隨着更新版本的編譯器增加了增強的類型檢查特性可能會報新的錯誤)。

新的--strict編譯器選項包含了一些建議配置的類型檢查選項。具體來說,指定--strict相當於是指定了以下所有選項(未來還可能包括更多選項):

  • --strictNullChecks
  • --noImplicitAny
  • --noImplicitThis
  • --alwaysStrict

未來的 TypeScript 版本可能會在這個集合中添加額外的類型檢查選項。這意味着咱們不需要監控每個 TypeScript 版本來獲得應該在項目中啟用的新嚴格性選項。如果向上述選項集添加了新選項,則在升級項目的 TypeScript 版本后,它們將自動激活。

--strict 編譯選項會為以上列出的編譯器選項設置默認值。這意味着還可以單獨控制這些選項。比如:

--strict --noImplicitThis false 

或者在tsconfig.json 文件指定:

{
  "strict": true, "alwaysStrict": false } 

這將是開啟除--noImplicitThis編譯選項以外的所有嚴格檢查選項。使用這個方式可以表述除某些明確列出的項以外的所有嚴格檢查項。換句話說,現在可以在默認最高級別的類型安全下排除部分檢查。

改進的 --init 輸出

除了默認的--strict設置外,tsc --init還改進了輸出。tsc --init默認生成的tsconfig.json文件現在包含了一些帶描述的被注釋掉的常用編譯器選項. 你可以去掉相關選項的注釋來獲得期望的結果。我們希望新的輸出能簡化新項目的配置並且隨着項目成長保持配置文件的可讀性。

通過 tsc --init 編譯器可以為構建一個配置文件:

$ tsc --init
message TS6071: Successfully created a tsconfig.json file.

運行此命令后,會當前工作目錄中生成一個tsconfig.json文件,生成的配置如下所示:

{
  "compilerOptions": { /* Basic Options */ "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'. */ "module": "commonjs", /* Specify module code generation: 'commonjs', 'amd', 'system', 'umd' or 'es2015'. */ // "lib": [], /* Specify library files to be included in the compilation: */ // "allowJs": true, /* Allow JavaScript files to be compiled. */ // "checkJs": true, /* Report errors in .js files. */ // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ // "declaration": true, /* Generates corresponding '.d.ts' file. */ // "sourceMap": true, /* Generates corresponding '.map' file. */ // "outFile": "./", /* Concatenate and emit output to single file. */ // "outDir": "./", /* Redirect output structure to the directory. */ // "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ // "removeComments": true, /* Do not emit comments to output. */ // "noEmit": true, /* Do not emit outputs. */ // "importHelpers": true, /* Import emit helpers from 'tslib'. */ // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ /* Strict Type-Checking Options */ "strict": true /* Enable all strict type-checking options. */ // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ // "strictNullChecks": true, /* Enable strict null checks. */ // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ /* Additional Checks */ // "noUnusedLocals": true, /* Report errors on unused locals. */ // "noUnusedParameters": true, /* Report errors on unused parameters. */ // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ /* Module Resolution Options */ // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ // "typeRoots": [], /* List of folders to include type definitions from. */ // "types": [], /* Type declaration files to be included in compilation. */ // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ /* Source Map Options */ // "sourceRoot": "./", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ // "mapRoot": "./", /* Specify the location where debugger should locate map files instead of generated locations. */ // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ /* Experimental Options */ // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ } }

注意 --strict 是默認啟用的。這意味着在啟動一個新的TypeScript項目時,自動進入默認模式。

--checkJS 選項下 .js 文件中的錯誤

即便使用了--allowJs,TypeScript 編譯器默認不會報 .js 文件中的任何錯誤。TypeScript 2.3 中使用--checkJs選項,.js文件中的類型檢查錯誤也可以被報出.

你可以通過為它們添加// @ts-nocheck注釋來跳過對某些文件的檢查,反過來你也可以選擇通過添加// @ts-check注釋只檢查一些.js文件而不需要設置--checkJs編譯選項。你也可以通過添加// @ts-ignore到特定行的一行前來忽略這一行的錯誤.

.js文件仍然會被檢查確保只有標准的 ECMAScript 特性,類型標注僅在.ts文件中被允許,在.js中會被標記為錯誤。JSDoc注釋可以用來為你的 JS 代碼添加某些類型信息,


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM