javascript
javascript 迁移 typescript 实践
只是抱著嘗試的心態(tài)對項(xiàng)目進(jìn)行了遷移,體驗(yàn)了一番typeScript的強(qiáng)大,當(dāng)然,習(xí)慣了JavaScript的靈活,弱類型,剛用上typeScript時(shí)會很不適應(yīng),猶如懶散慣了的人被突然箍上各種枷鎖,約束。但是,從長遠(yuǎn)來看,尤其是多人協(xié)作的項(xiàng)目,還是很有必要的。
typescript的優(yōu)點(diǎn)
- 靜態(tài)代碼檢查
可以規(guī)避一些容易被忽視,隱晦的邏輯或語法錯(cuò)誤,幫助我們寫更加健壯,安全的代碼,如下所示
function getDefaultValue (key, emphasis) {let ret;if (key === 'name') {ret = 'GuangWong';} else if(key=== 'gender') {ret = 'Man';} else if (key === 'age') {ret = 23;} else {throw new Error('Unkown key ');}if (emphasis) {ret = ret.toUpperCase();}return ret;}getDefaultValue('name'); // GuangWonggetDefaultValue('gender', true) // MANgetDefaultValue('age', true)這是一個(gè)簡單的函數(shù),第一個(gè)參數(shù) key 用來獲得一個(gè)默認(rèn)值。第二參數(shù) emphasis 為了某些場景下要大寫強(qiáng)調(diào),只需要傳入 true 即可自動(dòng)將結(jié)果轉(zhuǎn)成大寫。
但是如果不小心將 age 的值寫成了數(shù)字字面量,如果我調(diào)用 getDefaultValue('age', true) 就會在運(yùn)行時(shí)報(bào)錯(cuò)。這個(gè)有可能是業(yè)務(wù)上線了之后才發(fā)生,直接導(dǎo)致業(yè)務(wù)不可用。
- 提高效率,錯(cuò)誤在編寫代碼時(shí)報(bào)錯(cuò),而非編譯階段
如有一種場景,在代碼重構(gòu)遷移模塊目錄時(shí),一些模塊依賴引用路徑變更,或者是引用的模塊還沒安裝,不存在時(shí),配合vscode, 及時(shí)指出錯(cuò)誤,不用等跑一遍編譯
這種情況也適用于引用非定義變量等錯(cuò)誤
- 增強(qiáng)代碼的可讀性,可以做到代碼即文檔。
雖然代碼有注釋,但是并不是每個(gè)人都有良好的習(xí)慣
react 組件設(shè)計(jì)export interface CouponProps { coupons: CouponItemModel[]; }export interface couponState {page: number,size: number }class CouponContainer extends React.Component<CouponProps, couponState> {render() {return (<div>{this.props.coupons.map((item: CouponItemModel) => item.title)}</div>)} }使用 JS 寫的 Component,Props 和 State表現(xiàn)的并不明顯。使用 Typescript 編寫 React 組件,需要為組件定義好 Props 和 State。而這也被證明是個(gè)好的編碼方式。其可以幫助你構(gòu)建更健壯的組件,別人經(jīng)手自己的代碼時(shí)可以很清楚知道一個(gè)組件需要傳入哪些參數(shù)- 增強(qiáng)設(shè)計(jì)
相關(guān)實(shí)踐
實(shí)踐是消弭困惑最好的方式,抱著好奇,排斥的心態(tài)還是對對項(xiàng)目進(jìn)行了遷徙
--
如上圖所示,項(xiàng)目中所有源碼都放在src目錄中,src/client為客戶端的源碼,src/server為服務(wù)器端的代碼,dist目錄是編譯后的目錄
2. typescript In node
2.1.準(zhǔn)備階段
使用npm安裝:npm install -g typescript,當(dāng)前項(xiàng)目使用了是v2.8.3
2.2 tsconfig.json
在項(xiàng)目的根目錄下新建立tsconfig.json文件,并編輯相關(guān)配置項(xiàng)
相關(guān)配置解析可參考tsconfig.json
2.3 結(jié)合gulp
var gulp = require('gulp'); var pump = require('pump'); var webpack = require('webpack'); var gutil = require('gulp-util'); var webpackDevConfig = require(__dirname + '/webpack.config.dev.js');var ts = require('gulp-typescript'); var livereload = require('gulp-livereload'); var tsProject = ts.createProject("tsconfig.json");gulp.task('compile:tsc:server', function () {return gulp.src('src/server/**/*.ts').pipe(tsProject()).pipe(gulp.dest('dist/server')); });gulp.task('compile:tsc:client', function(callback){webpack(webpackDevConfig, function(err, stats){if(err) throw new gutil.PluginError("webpack:build-js", err);gutil.log("[webpack:build-js]", stats.toString({colors: true}));callback();}); });//將任務(wù)同步執(zhí)行 var gulpSequence = require('gulp-sequence');gulp.task('copy:html', function() {return pump([gulp.src('./src/views/**/*'),gulp.dest('./dist/server/views')]) });gulp.task('compile', gulpSequence('compile:tsc:server','compile:tsc:client','copy:html' ))gulp.task('watch', ['compile'], function() {livereload.listen();gulp.watch(['./src/server/**/*.ts'], ['compile:tsc:server']);gulp.watch(['./src/client/**/*.ts'], ['compile:tsc:client']);gulp.watch(['./src/views/**/*.html'], ['copy:html']); })2.4 測試
在src/server/app.ts下編寫代碼
2.5 遇到的問題
- 動(dòng)態(tài)地為global添加屬性
由于js靈活的風(fēng)格,我們經(jīng)常動(dòng)態(tài)地為某一對象添加屬性,但是typeScript是編譯型語言,基本原則是先定義再使用,所以當(dāng)我們像下面這么引用
global.testName = '哈哈';便會出現(xiàn)這樣的錯(cuò)誤
類型“Global”上不存在屬性“testName”解決方法
(1)將global強(qiáng)制轉(zhuǎn)化為any類型(<any>global).testName = '哈哈'(2)擴(kuò)展原有的對象global.prototy.testName = '哈哈哈'(3)使用.d.ts文件 declare namespace NodeJS {export interface Global {testName: string;} }網(wǎng)上很多方法是直接添加一個(gè).d.ts文件即可,但是親測無效,需要在引用文件引入該文件,如本項(xiàng)目在app.ts文件中引入了
/// <reference path="../types/custom.d.ts" />集成單元測試
項(xiàng)目用的測試框架是 jest + enzyme
npm i -D jest @types/jest
npm i -D ts-jest
npm i -D enzyme @types/enzyme
4.編寫測試用例 coupon.test.tsx
import * as React from 'react'; import { shallow, configure } from 'enzyme'; import * as Adapter from 'enzyme-adapter-react-16';configure({ adapter: new Adapter()})test('Jest-React-TypeScript 嘗試運(yùn)行', () => {const renderer = shallow(<div>hello world</div>)expect(renderer.text()).toEqual('hello world') })總結(jié)
以上是生活随笔為你收集整理的javascript 迁移 typescript 实践的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 你真的会使用Glide吗?——Glide
- 下一篇: gradle idea java ssm