typescript難學(xué)嗎?前端有必要學(xué)?該怎么學(xué)typescript
TypeScript代碼與 JavaScript 代碼有非常高的兼容性,無門檻,你把 JS 代碼改為 TS 就可以運行。如果沒有接觸過強類型的編程語言,導(dǎo)致他們認(rèn)為學(xué)習(xí)TS需要定義各種類型,還有一些新概念等等,會增加學(xué)習(xí)成本。TypeScript 應(yīng)該不會脫離 JavaScript 成為獨立的語言。學(xué)習(xí) TypeScript 應(yīng)該主要指的是學(xué)習(xí)它的類型系統(tǒng)。
什么是 TypeScript
微軟發(fā)布了一款 JavaScript 超集的編程語言并取名為 TypeScript,由于 TypeScript 是 JavaScript 的嚴(yán)格超集,因此任何 JavaScript 都是合法的 TypeScript(非常像 C 和 Objective-C 的關(guān)系)。TypeScript 為 JavaScript 帶來了強大的類型系統(tǒng)和對 ES2015的支持,它的編譯工具可以運行在任何服務(wù)器和任務(wù)系統(tǒng)上。
事實上 ES2015 發(fā)布之后 JavaScript 取得了巨大的進(jìn)步,但隨著設(shè)備性能的提升以及 JavaScript 在應(yīng)用層上不斷占據(jù)了重要的位置,對于大型項目,人們顯然需要更強大的語言級別的支持(微軟發(fā)現(xiàn)外部客戶在開發(fā)大規(guī)模 JavaScript 應(yīng)用的過程中遭遇的語言本身的短板)。
類型系統(tǒng)實際上是非常好的文檔,增強了編輯器在 智能提示
,跳轉(zhuǎn)定義
,代碼補全
等方向上的功能,并且在編譯階段能發(fā)現(xiàn)大部分的錯誤,對于大型工程的代碼可讀性和可維護(hù)性起到了了不起的作用。
TypeScript 的流行趨勢
事實上 TypeScript 擁有活躍的社區(qū),大部分第三方庫都有提供 TypeScript 類型定義文件,甚至知名的前端庫都完全使用 TypeScript 來進(jìn)行開發(fā),比如 Google 的 Angular,我們可以通過一些數(shù)據(jù)來了解 TypeScript 的流行趨勢:
TypeScript 的優(yōu)勢和收益是什么
TypeScript 官網(wǎng)上列了很多它的優(yōu)勢,在這里我更愿意自己總結(jié)一下:
- 類型系統(tǒng)可在編譯階段發(fā)現(xiàn)大部分的錯誤
- 類型系統(tǒng)也是一個很直觀的編程文檔,可以查看任何函數(shù)或API的輸入輸出類型
- 類型系統(tǒng)增強了編輯器或IDE的功能
- TypeScript 可以自動的推導(dǎo)類型
- 一切 JavaScript 都是合法的 TypeScript 降低了使用成本
- TypeScript 擁抱 ES2015 以及 ESNext 草案規(guī)范
- 幾乎第三方庫都有 TypeScript 類型定義文件
如果你有一個需要長期維護(hù)的工程,那么類型系統(tǒng)在可讀性和可維護(hù)性上擁有比 JavaScript 更強大的動能,在良好的編程語境下,在穩(wěn)定的工具鏈幫助下,TypeScript 可以說是目前唯一較好的選擇。
當(dāng)然,凡事都有兩面性,TypeScript 有一定的學(xué)習(xí)成本,比如:Interfaces,Generics,Enums 等前端工程師不是很熟悉的概念,短期內(nèi)多少會增加一些開發(fā)成本,集成和構(gòu)建一些庫會有一定的工作量,比如我們用 React 來開發(fā)一個前端工程,那么你就需要進(jìn)行一些配置,當(dāng)然你也可以直接使用 create-react-app 來創(chuàng)建一個 TypeScript + React 工程。
TypeScript 與 JavaScript 對比表格
| 對比項目 | TypeScript | JavaScript | 注意 | | --------| --- | --- | --- | | 基本類型 | boolean number string Array Tuple Enum any void null undefined never object | string number boolean null undefined symbol | TypeScript 中 object 表示的是不是 JavaScript 基本類型的類型| | 變量聲明 | let const var| let const var | 基本一致 | | 接口 | interface | 無 | TypeScript 的核心是類型檢查,因此接口充當(dāng)了命名這些類型的角色 | | 類 | class abstract class readonly … | class 無 abstract class | 基本一致,但不同的可能發(fā)生在未來,TypeScript 使用 private 來定義私有,而 JavaScript 未來極有可能將 #.xx 來定義私有寫入標(biāo)準(zhǔn)。TypeScript 支持抽象類,只讀等等。| | 函數(shù) | N | N | 基本一致,參數(shù)賦默認(rèn)值,剩余參數(shù)等等,唯一不同的是 TypeScript 支持?可選參數(shù) | | 泛型 | Generics | 無 | 泛型是一個特別靈活的可重用指定不同類型來控制具體類型的類型,TypeScript 支持 | | 枚舉 | Enums | 無 | TypeScript 支持的枚舉不僅可以默認(rèn)從 0 開始,也可以賦值具體的字符串,它的操作空間非常大 | | 類型推斷 | 支持 | 無 | let x = 3; TypeScript 可以通過 3 來推斷 x 的類型是 number | | 高階類型 | & typeof instanceof … | 無 | TypeScript 獨有 | | Symbols | N | N | Symbol 一樣 | | 迭代器 | N | N | 如果實現(xiàn)了 Symbol.iterator ,那么就被視為可迭代的,術(shù)語上和 JavaScript 定義的一樣 | | Generators | N | N | 一樣 | | 模塊系統(tǒng) | N | export import | 事實上 TypeScript 支持多種多樣的模塊系統(tǒng),既有 ESModule 也有 Commonjs 規(guī)范,甚至還有 AMD UMD 等 | | 其他 | N | N | 由于 TypeScript 是 JavaScript 的超集,因此 ES2016 之后以及 ESNext 定義的 api 都可以直接在 TypeScript 中使用 并不需要語言支持,至于其他一些比如 JSX Mixins 等等,由于這些不屬于 JavaScript 標(biāo)準(zhǔn)因此這里不再復(fù)述 。|
環(huán)境配置
TypeScript 3.3
既然上文我們了解到 TypeScript 需要編譯,那么我們肯定會使用到編譯工具,因此在我們開始正式學(xué)習(xí) TypeScript 之前需要安裝一下編譯環(huán)境。
- 安裝 Node.js 10.15.3 LTS
- 安裝 typescript
$ npm install -g typescript $ tsc --version
國際慣例 Hello World
創(chuàng)建一個 helloworld.ts
文件,然后輸入:
let helloworld = ""; console.log(helloworld); $ tsc helloworld.ts
現(xiàn)在我們稍微改動一行代碼,在 JavaScript 中我們完全可以如此:
let helloworld = ""; helloworld = 1;
對于語法而言這完全是正確的,但對于語句來說,不能鎖定類型在某些情況下,很容易出現(xiàn)未知異常的問題,現(xiàn)在我們執(zhí)行 tsc
來編譯它:
$ tsc helloworld.ts helloworld.ts:5:1 - error TS2322: Type '1' is not assignable to type 'string'. 5 helloworld = 1; Found 1 error.
編譯器可以明確的告知你不能將 1
賦值給字符串類型,這就是 TypeScript 帶來的魅力。
tsconfig.json
tsconfig.json
文件可以指定編譯 TypeScript 項目所需的根目錄以及編譯器選項,如果你的工程中存在 tsconfig.json
則表示 tsconfig.json
所在的目錄為你 TypeScript 工程的根目錄。
使用 tsconfig.json
的規(guī)則:
- 如果你直接運行
tsc
在這種情況下,編譯器將從當(dāng)前目錄開始搜索tsconfig.json
并向上查找 - 你也可以直接運行
tsc -p xxx
在這種情況下,xxx 目錄上必須存在tsconfig.json
文件 - 如果在命令行中直接輸出文件
tsc helloworld.ts
編譯器將忽略tsconfig.json
文件
當(dāng)然你可以直接使用 tsc --init
在當(dāng)前運行的目錄中創(chuàng)建一個 tsconfig.json
(推薦)。
{ "compilerOptions": { /* Basic Options */ "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */ "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ // "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. */ // "declarationMap": true, /* Generates a sourcemap for each 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. */ // "composite": true, /* Enable project compilation */ // "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. */ // "strictFunctionTypes": true, /* Enable strict checking of function types. */ // "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */ // "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */ // "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. */ "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ /* 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. */ } }
編譯器選項
這些編譯器選項也是 tsconfig.json
中的配置項
當(dāng)你不想通過 tsconfig.json
來配置編譯器的話,也可以使用如下的編譯器選項通過命令行來運行編譯器執(zhí)行編譯任務(wù),這里只介紹幾個常用的,其他的配置請參考 Compiler Options 表格。
--watch 或 -w
監(jiān)視輸入文件的更改并觸發(fā)重新編譯--version 或 -v
查看編譯器的版本--types=["字符串"]
類型描述文件的名稱列表--target=""
指定編譯的 ECMAScript 的版本,默認(rèn)版本是 ES3--strict
啟用所有嚴(yán)格類型檢查--sourceMap
生成對應(yīng)的 .map 文件--outFile
輸出到單個文件--outDir
輸出到目錄--module 或 -m
指定使用哪種模塊標(biāo)準(zhǔn)來輸出代碼,選項有 "None", "CommonJS", "AMD", "System", "UMD", "ES6", "ES2015" or "ESNext"--lib
要包含在編譯中的庫文件列表,比如 ES2015.Promise--jsx
在.tsx
文件中支持JSX
可指定要編譯輸出的JSX
類型
與 Webpack 集成
事實上我們不可能只單獨的使用 TypeScript 而是要將它融入到現(xiàn)有的技術(shù)棧中和工具結(jié)合起來,至少目前為止多數(shù)的前端工程都將 Webpack 視為標(biāo)準(zhǔn)配置,因此 TypeScript 編譯器和 Webpack 集成在一起,這非常有用。
awesome-typescript-loader
是 TypeScript 提供的在 Webpack 中使用的 loader,因此我們只需要:
$ yarn add typescript awesome-typescript-loader source-map-loader --dev
然后在你的 webpack.config.json
文件中配置即可:
var fs = require('fs') var path = require('path') var webpack = require('webpack') const { CheckerPlugin } = require('awesome-typescript-loader'); var ROOT = path.resolve(__dirname) module.exports = { entry: './src/index.tsx', devtool: 'inline-source-map', output: { path: ROOT + '/dist', filename: '[name].bundle.js', sourceMapFilename: '[name].bundle.map.js', publicPath: '//localhost:8889/dist/', }, devServer: { inline: true, quiet: true, contentBase: "./", port: 8889 }, module: { rules: [ { test: /\.ts[x]?$/, loader: "awesome-typescript-loader" }, { enforce: "pre", test: /\.ts[x]$/, loader: "source-map-loader" }, ] }, resolve: { extensions: [".ts", ".tsx"], alias: { '@': path.resolve(ROOT,'src') } }, plugins: [ new CheckerPlugin(), ] }
結(jié)語
這篇文章簡單介紹了 該怎么學(xué)typescript,有一句古話:了解歷史才能真正了解這些故事,時代變化 JavaScript 可以說是目前為止唯一實現(xiàn)了 Write Once Run Anywhere 的腳本語言(當(dāng)然 C 語言才是),它的熱度和趨勢長久不衰,但 JavaScript 本身也有其語言的缺陷,也許在未來新的標(biāo)準(zhǔn)會慢慢補齊它,至少現(xiàn)在讓我們用 TypeScript 來解決你可能面臨的問題吧。
到此這篇關(guān)于typescript難學(xué)嗎?前端有必要學(xué)?該怎么學(xué)typescript的文章就介紹到這了,更多相關(guān)前端學(xué)typescript內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
TypeScript Module Resolution解析過程
這篇文章主要為大家介紹了TypeScript Module Resolution解析過程,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-07-07TS報錯Cannot?find?module?'xxx'?or?its?correspo
這篇文章主要為大家介紹了TS報錯Cannot?find?module?'xxx'?or?its?corresponding?type?declarations解決,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-08-08TypeScript實現(xiàn)十大排序算法之冒泡排序示例詳解
這篇文章主要為大家介紹了TypeScript實現(xiàn)十大排序算法之冒泡排序示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-02-02CKEditor4配置與開發(fā)詳細(xì)中文說明文檔
網(wǎng)上分享的CKEditor4中文說明很多都只是的部分使用方法,今天為大家分享一下比較完整的CKEditor4中文說明文檔2018-10-10TypeScript中的數(shù)據(jù)類型enum?type?interface基礎(chǔ)用法示例
這篇文章主要為大家介紹了TypeScript中的數(shù)據(jù)類型enum?type?interface基礎(chǔ)用法示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-08-08ThreeJS使用紋理貼圖創(chuàng)建一個我的世界草地方塊
這篇文章主要為大家介紹了ThreeJS使用紋理貼圖創(chuàng)建一個我的世界草地方塊的實現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-06-06