布爾 數字javascript
元祖css
const author:[string, string] = ['mx', '大風']
複製代碼
枚舉, 好比應用於訂單狀態html
enum Order {
finish = '訂單完成',
deleted = '訂單刪除',
send = '訂單已發出'
}
複製代碼
any 放棄類型檢查html5
function users(name?:string) {
console.log(name)
}
function users(age:number = 18, name?:string) {
console.log(name)
}
function users(...numbers: number[]) {
console.log(name)
}
複製代碼
public private protectedjava
public name: string; //類裏面 子類 其它任何地方外邊均可以訪問
protected age: number; //類裏面 子類 均可以訪問,其它任何地方不能訪問
private money: number; //類裏面能夠訪問, 子類和其它任何地方都不能夠訪問
複製代碼
安裝 TypeScript 時,會順帶安裝 lib.d.ts 聲明文件。此文件包含了 JavaScript 運行時以及 DOM 中存在各類常見的環境聲明node
對於項目中一些全局可用的變量或者接口,能夠考慮建立一個globals.d.tsreact
globals.d.ts 能夠看作是 lib.d.ts 的擴充webpack
TypeScript的核心原則之一是對值所具備的結構進行類型檢查git
在TypeScript裏,接口的做用就是爲這些類型命名和爲你的代碼或第三方代碼定義契約。es6
定義屬性
interface props {
readonly name: string
habit? : string
}
複製代碼
定義一個函數所需的形狀
interface fnBox {
(len:number, cont: number): number[]
}
let pushAry:fnBox
pushAry = function (len: number, cont: number) {
return new Array(len).fill(cont)
}
複製代碼
若是這裏故意寫錯cont的類型,會有什麼提示
能夠定義無返回值的函數
interface props {
once(): void
twice: () => void
}
複製代碼
咱們也可使用函數表達式去書寫函數
let sing = () => {-- do something --}
複製代碼
函數表達式添加約束能夠寫爲
let sing = (singer: string): boolean => {-- do something --}
複製代碼
可是這種只是對等號右側的匿名函數進行了類型定義,而等號左邊的 sing,是經過賦值操做進行類型推論而推斷出來的
手動給 sing 添加類型,則應該是這樣:
let sing: (singer: string) => boolean = (singer: string): boolean => { -- do something-- }
複製代碼
implements 可使類 具備接口的屬性功能
interface int2 {
once(): void,
touchMore: (count: number) => void
}
class Btn implements int2 {
once () {
console.log('once')
}
touchMore (count: number) {
console.log('touchMore')
}
}
const btns = new Btn
btns.once()
btns.touchMore(9)
複製代碼
1 使用webpack搭建項目的時候,有配置alias參數
'utils': path.resolve(__dirname, '../utils')
複製代碼
這樣在組件中引入的時候,文件路徑能夠簡化
import { log } from 'utils/statistics'
複製代碼
不過在使用ts以後,會發現組件中有警告信息,表示找不到此模塊
就須要另外在tsconfig中添加配置參數
"baseUrl": "./",
"paths": {
"components": ["./components/*"],
"utils": ["./utils/*"],
}
複製代碼
2 other
noEmitOnError: true
複製代碼
當編譯出錯,則不輸出編譯後的文件
在訪問頁面的時候,server會反饋一些基本的用戶信息,好比用戶名,設備版本號等,將這些所有掛載在CONFIG變量中了
<script type="text/javascript">
window.CONFIG = JSON.parse(decodeURIComponent('{{feConfig}}'))
</script>
const {uid, version} = window.CONFIG // 而後在組件中能夠直接獲取
複製代碼
可是在加入TS以後,會提示window中不存在屬性CONFIG
TS不容許獲取,設置沒有聲明過的屬性,因此這裏報錯了
處理方案
1 全局擴展
在模塊內部添加聲明到全局做用域
在入口文件index.tsx中 添加聲明
declare global {
interface Window { CONFIG: any }
}
const {uid} = window.CONFIG
複製代碼
2 使用類型斷言
const { apk } = (window as any).CONFIG
複製代碼
3 添加 globals.d.ts 聲明文件
interface Window {
CONFIG: any
}
複製代碼
import * as React from 'react'
class App extends React.Component<props, state>{
-- do something --
}
複製代碼
泛型是指在定義函數、接口或類的時候,不預先指定具體的類型,而在使用的時候再指定類型的一種特性
好比寫一個根據指定內容填充到指定長度的數組生成函數 getAry
function getAry (len: number, cont: string | number): string[] | number[] {
return new Array(len).fill(cont)
}
複製代碼
參數
參數 | 含義 | 類型 |
---|---|---|
len | 指定長度 | number |
cont | 指定內容 | string 或 number (使用聯合類型處理) |
因爲不肯定參數cont的輸入類型,因此返回值使用了聯合類型處理
這種須要 返回值類型和輸入參數類型保持一致的狀況,可使用泛型T來處理
泛型是類型變量,一種用來表示類型的特殊變量
在函數名後添加<>
function createFn<T>
function createFn<string> // 明確指定 T 是 string 類型的
複製代碼
其實泛型函數的類型與非泛型函數的類型沒什麼不一樣,只是多了一個類型參數在最前面
TypeScript 2.3 之後,咱們能夠爲泛型中的類型參數指定默認類型。當使用泛型時沒有在代碼中直接指定類型參數,從實際值參數中也沒法推測出時,這個默認類型就會起做用
function beConfusion<T = boolean> (name: string, isDone: boolean) {...}
複製代碼
將上面那個函數使用接口來定義
interface dealFn {
<T>(len: number, cont: T): T[]
}
let getAry: dealFn
getAry = function <T> (len: number, cont: T): T[] {
--do something--
}
複製代碼
泛型類使用<>括起泛型類型,跟在類名後面
class DealAry<T> {
value: T
constructor (value: T) {
this.value = value
}
deal () {
console.log(this.value)
}
}
複製代碼
雖然能夠本身定義泛型變量結構,可是通常會使用已定義好的泛型
Promise
async taobaoGoods = function (ids: number[]): Promise<string> {
return new Promise <string>((reslove, reject) => {
try{
reslove('success')
} catch {
reject('failture')
}
})
}
複製代碼
class 複製代碼
打開 node_modules/@types/react 能夠看到 component 類
簡單歸納就是
class Component<P = {} , S = {} > {
-- other --
readonly props: Readonly<{ children?: ReactNode }> & Readonly<P>
state: Readonly<S>
-- other --
}
複製代碼
能夠看到 props 和 state 兩個對象都是隻讀的
因此咱們在寫React組件的時候,要調整爲
interface BannerProps {
showUpdate(): void,
clickOnce: (type: string, id: number) => void
}
interface BannerState {
once: boolean
}
export default class Banner extends React.Component<BannerProps, BannerState> {
--do something--
}
複製代碼
獲取一個元素的某個屬性
componentDidMount () {
const target = this.refs.img
if (target.getAttribute('src') != newSrc) { -- do something-- }
}
複製代碼
ts提示有錯誤
這是由於TS推斷target 還不具有getAttribute 屬性
TypeScript 容許你覆蓋它的推斷,而且能以你任何你想要的方式分析它,這種機制,被稱爲「類型斷言」
TypeScript 類型斷言用來告訴編譯器你比它更瞭解這個類型,而且它不該該再發出錯誤
<類型>值 或者 值 as 類型
複製代碼
*** 在jsx中必須使用 第二種方式去處理 ***
在不肯定類型的時候就訪問其中一個類型的屬性或方法,可使用類型斷言
function getType (arg: string | boolean): boolean {
if ( arg.length ) return true
return false
}
複製代碼
這種其實會報錯的,若是輸入是布爾值,則沒有length
加入類型斷言
function getType (arg: string | boolean): boolean {
if ( (arg as string).length ) return true
// if ( (<string>arg).length ) return true
return false
}
複製代碼
斷言成一個聯合類型中不存在的類型是不容許的
if ( (arg as array).length ) return true // 報錯
複製代碼
因此上面組件裏 須要調整爲
const target = this.refs.img as HTMLElement
複製代碼
JavaScript 中有不少內置對象,能夠直接在 TypeScript 中當作定義好了的類型
const isEnd:Boolean = new Boolean(false)
interface createEle {
createElement(tagName: "div"): HTMLDivElement
}
複製代碼
interface videoProps {
poster?: string
}
class Video extends Component<videoProps> {
static defaultProps = {
poster: ''
}
}
複製代碼
新項目中將webpack部分調整爲ts處理
參考文章,官網地址
儲備知識
ts-node 能夠直接運行.ts文件 ts版本使用方式見官網
tsconfig.webpack.json中的配置直接按照官網中去寫的
{
"compilerOptions": {
"module": "commonjs",
"target": "es5",
"esModuleInterop": true
}
}
複製代碼
這裏配置的是es5 將其調整爲es6便可
或者使用 webpack-merge 進行模塊合併
const config: Configuration = merge(commonPlugin, {...})
複製代碼
項目中保留了一份 webpack.common.js的文件,發如今 import 模塊的時候 會先找到 這個.js的 而不是 .ts
import commonPlugin from './webpack.common'
複製代碼
ts.config 中有一個 allowJs 參數 若是設置爲TRUE 則能夠引入js文件 可是這個默認的是FALSE 因此應該不會有引入 js文件
因此很奇怪 - 文檔
暫時將js文件名修改了
<Banner once={::this.update} />
複製代碼
這個主要是藉助了bable 的 transform-function-bind 雙冒號實現綁定
TS不支持這種寫法 能夠調整爲
<Banner once={() => this.update} />
<Channel clickOnce={this.clickOnce.bind(this)} /> 複製代碼
組件中有使用
const result = Object.assign({}, params, info)
複製代碼
處理方案
1 藉助lodash
安裝lodash.assign和@types/lodash
2 更換複製對象方案
3 調整tsconfig配置文件
以前
target: es5
複製代碼
調整爲
target: es6
複製代碼
注意可能須要重啓 VScode 才能夠生效
3 img 元素屬性
在獲取img元素的src屬性的時候,是這麼寫的
(target as HTMLElement).getAttribute('src')
複製代碼
而後在直接設置src值的時候
(item as HTMLElement).src = itemSrc
複製代碼
這樣就會報錯,須要調整爲
(item as HTMLImageElement).src = itemSrc
複製代碼
getAttribute 屬於 HTMLElement 屬性,而 src 屬於 HTMLImageElement 的屬性
補充一下 element HTMLElement node 的屬性方法
後續還在調整中,繼續更新掉坑記錄部分