TypeScript泛型參數(shù)默認(rèn)類(lèi)型和新的strict編譯選項(xiàng)
概述
TypeScript 2.3 增加了對(duì)聲明泛型參數(shù)默認(rèn)類(lèi)型的支持,允許為泛型類(lèi)型中的類(lèi)型參數(shù)指定默認(rèn)類(lèi)型。
接下來(lái)看看如何通過(guò)泛型參數(shù)默認(rèn)將以下react組件從js(和jsX)遷移到 TypeScript (和TSX):
class Greeting extends react.Component { render() { return <span>Hello, {this.props.name}!</span>; } }
為組件類(lèi)創(chuàng)建類(lèi)型定義
咱們先從為Component類(lèi)創(chuàng)建類(lèi)型定義開(kāi)始。每個(gè)基于類(lèi)的 React 組件都有兩個(gè)屬性:props和state,類(lèi)型定義結(jié)構(gòu)大致如下:
declare namespace React { class Component { props: any; state: any; } }
注意,這個(gè)是大大簡(jiǎn)化的示例,因?yàn)樵蹅兪菫榱搜菔痉盒皖?lèi)型參數(shù)及其默認(rèn)值的內(nèi)容。
現(xiàn)在就可以通過(guò)繼承來(lái)調(diào)用上面定義的Component:
class Greeting extends React.Component { render() { return <span>Hello, {this.props.name}!</span> } }
咱們可以如下方式創(chuàng)建組件的實(shí)例:
<Greeting name="world" />
渲染上面組件會(huì)生成以下html:
<span>Hello, World!</span>
nice,繼續(xù)。
使用泛型類(lèi)型定義 Props 和 State
雖然上面的示例編譯和運(yùn)行得很好,但是咱們的 Component 類(lèi)型定義不是很精確。因?yàn)樵蹅儗rops和state類(lèi)型設(shè)置為any,所以 TypeScript 編譯器也幫不上什么忙。
咱們得更具體一點(diǎn),通過(guò)兩種泛型類(lèi)型:Props和State,這樣就可以準(zhǔn)確地描述props和state屬性的結(jié)構(gòu)。
declare namespace React { class Component <Props, State> { props: Props; state: State; } }
接著創(chuàng)建一個(gè)GreetingProps類(lèi)型,該類(lèi)型定義一個(gè)字符串類(lèi)型name的屬性,并將其作為Props類(lèi)型參數(shù)的類(lèi)型參數(shù)傳遞:
type GreetingProps = { name: string }; class Greeting extends React.Component<GreetingProps, any> { render() { return <span>Hello, {this.props.name}!</span>; } }
1)GreetingProps是類(lèi)型參數(shù)Props的類(lèi)型參數(shù)
2) 類(lèi)似地,any是類(lèi)型參數(shù)State的類(lèi)型參數(shù)
有了這些類(lèi)型,咱們的組件得到更好的類(lèi)型檢查和自動(dòng)提示:
但是,現(xiàn)在使用React.Component類(lèi)時(shí)就必需供兩種類(lèi)型。咱們開(kāi)著的初始代碼示例就不在正確地進(jìn)行類(lèi)型檢查:
// Error: 泛型類(lèi)型 Component<Props, State> // 需要 2 個(gè)類(lèi)型參數(shù)。 class Greeting extends React.Component { render() { return <span>Hello, {this.props.name}!</span>; } }
如果咱們不想指定像GreetingProps這樣的類(lèi)型,可以通過(guò)為Props和State類(lèi)型參數(shù)提供any類(lèi)型來(lái)修正代碼:
class Greeting extends React.Component<any, any> { render() { return <span>Hello, {this.props.name}!</span>; } }
這種方法可以讓編譯器通過(guò),但咱們還有更優(yōu)雅的做法:泛型參數(shù)默認(rèn)類(lèi)型。
泛型參數(shù)默認(rèn)類(lèi)型
從 TypeScript 2.3 開(kāi)始,咱們可以為每個(gè)泛型類(lèi)型參數(shù)添加一個(gè)默認(rèn)類(lèi)型。在下面的例子中,如果沒(méi)有顯式地給出類(lèi)型參數(shù),那么Props和State都都是any類(lèi)型:
declare namespace React { class Component<Props = any, State = any> { props: Props; state: State; } }
現(xiàn)在,咱們就可以不用指定泛型類(lèi)型就可以通過(guò)編譯器的檢查:
class Greeting extends React.Component { render() { return <span>Hello, {this.props.name}!</span>; } }
當(dāng)然,咱們?nèi)匀豢梢燥@式地為Props類(lèi)型參數(shù)提供類(lèi)型并覆蓋默認(rèn)的any類(lèi)型,如下所示:
type GreetingProps = { name: string }; class Greeting extends React.Component<GreetingProps, any> { render() { return <span>Hello, {this.props.name}!</span>; } }
這兩個(gè)類(lèi)型參數(shù)現(xiàn)在都有一個(gè)默認(rèn)類(lèi)型,所以它們是可選的,咱們可以?xún)H為Props指定顯式的類(lèi)型參數(shù):
type GreetingProps = { name: string };
class Greeting extends React.Component<GreetingProps> { render() { return <span>Hello, {this.props.name}!</span>; } }
注意,咱們只提供了一個(gè)類(lèi)型參數(shù)。但是,被省略可選類(lèi)型參數(shù)前一個(gè)必須要指定類(lèi)型,否則不能省略。
其它事例
在上一篇中關(guān)于 TypeScript 2.2 中混合類(lèi)的文章中,咱們最初聲明了以下兩個(gè)類(lèi)型別名:
type constructor<T> = new (...args: any[]) => T; type constructable = Constructor<{}>;
Constructable類(lèi)型純粹是語(yǔ)法糖。它可以代替Constructor<{}>類(lèi)型,這樣就不必每次都要寫(xiě)泛型類(lèi)型參數(shù)。使用泛型參數(shù)默認(rèn)值,就可以完全去掉附加的可構(gòu)造類(lèi)型,并將{}設(shè)置為默認(rèn)類(lèi)型
type Constructor<T = {}> = new (...args: any[]) => T;
語(yǔ)法稍微復(fù)雜一些,但是生成的代碼更簡(jiǎn)潔,Good。
新的--strict主要編譯選項(xiàng)
TypeScript 2.3 引入了一個(gè)新的--strict編譯器選項(xiàng),它支持許多與更嚴(yán)格的類(lèi)型檢查相關(guān)的其他編譯器選項(xiàng)。
TypeScript 加入的新檢查項(xiàng)為了避免不兼容現(xiàn)有項(xiàng)目通常都是默認(rèn)關(guān)閉的。雖然避免不兼容是好事,但這個(gè)策略的一個(gè)弊端則是使配置最高類(lèi)型安全越來(lái)越復(fù)雜,這么做每次 TypeScript 版本發(fā)布時(shí)都需要顯示地加入新選項(xiàng)。有了--strict編譯選項(xiàng),就可以選擇最高級(jí)別的類(lèi)型安全(了解隨著更新版本的編譯器增加了增強(qiáng)的類(lèi)型檢查特性可能會(huì)報(bào)新的錯(cuò)誤)。
新的--strict編譯器選項(xiàng)包含了一些建議配置的類(lèi)型檢查選項(xiàng)。具體來(lái)說(shuō),指定--strict相當(dāng)于是指定了以下所有選項(xiàng)(未來(lái)還可能包括更多選項(xiàng)):
- --strictNullChecks
- --noImplicitAny
- --noImplicitThis
- --alwaysStrict
未來(lái)的 TypeScript 版本可能會(huì)在這個(gè)集合中添加額外的類(lèi)型檢查選項(xiàng)。這意味著咱們不需要監(jiān)控每個(gè) TypeScript 版本來(lái)獲得應(yīng)該在項(xiàng)目中啟用的新嚴(yán)格性選項(xiàng)。如果向上述選項(xiàng)集添加了新選項(xiàng),則在升級(jí)項(xiàng)目的 TypeScript 版本后,它們將自動(dòng)激活。
--strict編譯選項(xiàng)會(huì)為以上列出的編譯器選項(xiàng)設(shè)置默認(rèn)值。這意味著還可以單獨(dú)控制這些選項(xiàng)。比如:
--strict --noImplicitThis false
或者在tsconfig.json文件指定:
{ "strict": true, "alwaysStrict": false }
這將是開(kāi)啟除--noImplicitThis編譯選項(xiàng)以外的所有嚴(yán)格檢查選項(xiàng)。使用這個(gè)方式可以表述除某些明確列出的項(xiàng)以外的所有嚴(yán)格檢查項(xiàng)。換句話說(shuō),現(xiàn)在可以在默認(rèn)最高級(jí)別的類(lèi)型安全下排除部分檢查。
改進(jìn)的--init輸出
除了默認(rèn)的--strict設(shè)置外,tsc --init還改進(jìn)了輸出。tsc --init默認(rèn)生成的tsconfig.json文件現(xiàn)在包含了一些帶描述的被注釋掉的常用編譯器選項(xiàng). 你可以去掉相關(guān)選項(xiàng)的注釋來(lái)獲得期望的結(jié)果。我們希望新的輸出能簡(jiǎn)化新項(xiàng)目的配置并且隨著項(xiàng)目成長(zhǎng)保持配置文件的可讀性。
通過(guò)tsc --init編譯器可以為構(gòu)建一個(gè)配置文件:
$ tsc --init
message TS6071: Successfully created a tsconfig.json file.
運(yùn)行此命令后,會(huì)當(dāng)前工作目錄中生成一個(gè)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是默認(rèn)啟用的。這意味著在啟動(dòng)一個(gè)新的TypeScript項(xiàng)目時(shí),自動(dòng)進(jìn)入默認(rèn)模式。
--checkJS選項(xiàng)下.js文件中的錯(cuò)誤
即便使用了--allowJs,TypeScript 編譯器默認(rèn)不會(huì)報(bào).js文件中的任何錯(cuò)誤。TypeScript 2.3 中使用--checkJs選項(xiàng),.js文件中的類(lèi)型檢查錯(cuò)誤也可以被報(bào)出.
你可以通過(guò)為它們添加// @ts-nocheck注釋來(lái)跳過(guò)對(duì)某些文件的檢查,反過(guò)來(lái)你也可以選擇通過(guò)添加// @ts-check注釋只檢查一些.js文件而不需要設(shè)置--checkJs編譯選項(xiàng)。你也可以通過(guò)添加// @ts-ignore到特定行的一行前來(lái)忽略這一行的錯(cuò)誤.
.js文件仍然會(huì)被檢查確保只有標(biāo)準(zhǔn)的 ECMAScript 特性,類(lèi)型標(biāo)注僅在.ts文件中被允許,在.js中會(huì)被標(biāo)記為錯(cuò)誤。JSDoc注釋可以用來(lái)為你的 JS 代碼添加某些類(lèi)型信息,
以上就是TypeScript泛型參數(shù)默認(rèn)類(lèi)型和新的strict編譯選項(xiàng)的詳細(xì)內(nèi)容,更多關(guān)于TypeScript的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
JavaScript實(shí)現(xiàn)標(biāo)題欄文字輪播效果代碼
這篇文章主要介紹了JavaScript實(shí)現(xiàn)標(biāo)題欄文字輪播效果代碼,涉及JavaScript基于時(shí)間函數(shù)及流程控制操作標(biāo)題欄文字的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-10-10使用Auto.js?調(diào)用系統(tǒng)短信、電話模塊實(shí)現(xiàn)功能
這篇文章主要介紹了如何使用Auto.js調(diào)用系統(tǒng)短信與電話模塊,并實(shí)現(xiàn)讀取短信與聯(lián)系人的功能,并給出了實(shí)現(xiàn)相應(yīng)功能的代碼2023-03-03詳解XMLHttpRequest(一)同步請(qǐng)求和異步請(qǐng)求
這篇文章主要為大家詳細(xì)介紹了XMLHttpRequest 同步請(qǐng)求和異步請(qǐng)求,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-09-09關(guān)于Javascript加載執(zhí)行優(yōu)化的研究報(bào)告
這篇文章主要介紹了關(guān)于Javascript加載執(zhí)行優(yōu)化的研究報(bào)告,需要的朋友可以參考下2014-12-12echarts修改橫坐標(biāo)顏色簡(jiǎn)單代碼示例
這篇文章主要給大家介紹了關(guān)于echarts修改橫坐標(biāo)顏色的相關(guān)資料,在項(xiàng)?中常常會(huì)?到echarts的實(shí)例,根據(jù)不同的需求字體顏?需要變化,需要的朋友可以參考下2023-07-07JavaScript設(shè)計(jì)模式之外觀模式介紹
這篇文章主要介紹了JavaScript設(shè)計(jì)模式之外觀模式介紹,外觀模式是用于由于子系統(tǒng)或程序組成較復(fù)雜而提供的一個(gè)高層界面接口,使用客戶(hù)端更容易訪問(wèn)底層的程序或系統(tǒng)接口,需要的朋友可以參考下2014-12-12js將json格式的對(duì)象拼接成復(fù)雜的url參數(shù)方法
下面小編就為大家?guī)?lái)一篇js將json格式的對(duì)象拼接成復(fù)雜的url參數(shù)方法。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-05-05JavaScript實(shí)現(xiàn)的簡(jiǎn)單拖拽效果
這篇文章主要介紹了JavaScript實(shí)現(xiàn)的簡(jiǎn)單拖拽效果,涉及javascript針對(duì)鼠標(biāo)事件與頁(yè)面樣式的操作技巧,需要的朋友可以參考下2015-06-06