TypeScript踩坑(持續更新)

配置

爲JS編寫類型聲明文件(d.ts)

不少第三方庫已經有本身的類型聲明文件,好比@types/react,@types/react-native,這些須要單獨安裝,而例如mobx-react和mobx這種會自帶類型文件,不須要單獨安裝。react

咱們最近有個新項目,須要照顧到不一樣同窗,有的願意用TS,有的不想用TS,爲了照顧到雙方,全部的公共模塊都是JS寫的,因此須要單獨爲TS寫類型聲明文件,具體語法請參考TS官網的文檔,這裏只是講一些坑。json

集中管理,相對路徑導入

爲項目中的JS寫類型文件的時候,須要先引入對應的文件,而後以導入的路徑爲名字聲明一個模塊,最後在須要用到這個類型文件的地方用///來引入相對路徑。
目錄結構以下:react-native

- @types
    - BasePage.d.ts
- src
    - frame
        - BasePage.js
    - page
        - hotelList
            - index.tsx

類型聲明文件:babel

// BasePage.d.ts
import BasePage from '../src/frame/BasePage'
declare module "../src/frame/BasePage" {
    export default class BasePage{}
}

引入類型文件:this

// index.tsx
/// <reference path="../../../@types/BasePage.d.ts" />

若是是想設置全局的類型文件,能夠在tsconfig.json的paths字段裏面指定對應的路徑,這樣就不須要單獨用reference引入了。google

自動導入

上面那種方法雖然能夠將types文件集中管理,可是有個很麻煩的地方就是須要在引入BasePage模塊的地方手動引入d.ts文件,這個真的很繁瑣,這裏有個更好的方法。spa

- src
    - frame
        - BasePage.js
        - BasePage.d.ts
    - page
        - hotelList
            - index.tsx

index.tsx文件直接import導入BasePage就好了,不須要再專門引入BasePage.d.ts,這裏二者命名同樣,因此會自動識別BasePage.d.ts,可是BasePage.d.ts的語法也變化了一些。插件

// BasePage.d.ts
// 注意:這裏不須要再聲明declare module "BasePage"了,不然會識別不了
export default class BasePage{}

語法

1. Element implicitly has an 'any' type because type 'Test' has no index signature

class PageFlag {
    updatePageFlag(name: string, value: boolean) {
        this[name] = value;
    }
}

這裏我但願可以更新PageFlag中的數據,可是又不想對全部的屬性一一列舉出來,可是因爲沒有設置this[name]的類型,致使了報錯,這裏有幾種解決辦法。code

(1) 修改tsconfig.json裏的noImplicitAny爲false。

(2) 給this設置類型,可是很差的地方就是失去了類型判斷的意義,以下:

// 例2
interface IParams {
    [propName: string]: any
}
class PageFlag {
    updatePageFlag = (name: string, value: boolean) => {
        (<IParams>this)[name] = value
    }
}

(3) 手動列舉全部屬性

雖然這樣比較麻煩,可是一眼就能看出來PageFlag有哪些屬性,數據比較清晰。component

type pageFlag = "showLoading" | "showMask" | "showCalendar";
class PageFlag {
    showLoading: boolean = false;
    showMask: boolean = false;
    showCalendar: boolean = false;
    
    updatePageFlag = (name: pageFlag, value: boolean) => {
       this[name] = value
    }
}

export from

有些文件夾下面有不少文件,因此我喜歡增長一個index.ts文件來直接export from其餘文件,這樣在其餘地方引入的時候能夠直接import from目錄,相似以下:

// 咱們有個components文件夾,下面有不少組件文件(都是export default導出的),咱們能夠components下建立index.ts文件,裏面這麼寫(下):
export Hotel from './Hotel'
export * as HotelList from './HotelList'
export Header from './Header'

可是這兩種export from的方式在TS裏面都會編譯報錯,但是我在ES6裏面明明寫的好好的啊!!!
後來在google上找到了一個連接,原來這兩種export from的方式都只是提案,若是在ES6中則須要額外添加@babel/plugin-proposal-export-namespace-from 插件來支持,TS中不支持這些寫法。

clipboard.png

可是感受這個更像野路子,也許將來會支持,遂放棄,最後發現了另一種寫法,能夠完美解決這個問題。

export {default as Hotel} from './Hotel'
export {default as HotelList} from './HotelList'
export {default as Header} from './Header'

順便說一下,export from其實還有下面兩種寫法,可是這兩種寫法都是須要模塊export導出,而不是export default導出的。

export { Hotel } from './Hotel'
export * from './Hotel
相關文章
相關標籤/搜索