ts 在項目中的使用
本次分享內容只涉及項目初始階段如何引入ts及依賴插件的ts。
ts為類型系統,js沒有類型,為了在開發階段減少錯誤而引入的系統。
ts有單獨的配置文件,一般放在項目目錄下
tsconfig.json
{
"compilerOptions": {
"target": "esnext",
"useDefineForClassFields": true,
"module": "esnext",
"moduleResolution": "node",
"strict": true,
"jsx": "preserve",
"sourceMap": true,
"resolveJsonModule": true,
"esModuleInterop": true,
"lib": ["esnext", "dom"],
"experimentalDecorators":true,
"baseUrl": "./",
"paths": {
"@/*":["src/*"]
},
"types": ["vite/client"]
},
"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"]
}
ts與js運行時兩套系統,雖然有時候代碼是寫在一起的,但他們運行時也是各自運行各自的代碼。
比如 import {clone} from 'lodash'
,js系統引入的是clone函數,ts系統引入的是clone函數的類型。
1.ts 文件相關術語
- 模塊文件: 含有 export 或者 import 的文件,文件名通常為:
xx.ts
import lodash from 'lodash'
console.log(lodash)
- 聲明文件: 不含實際運行代碼 文件名通常為
xx.d.ts
聲明文件中
聲明文件也可以是模塊文件,但其不含實際運行代碼,所以導出的都是類型聲明
type A = {name:string}
declare const a:A
2. 引入ts
npm install typescript -D
typescript安裝后,其自帶瀏覽器上使用的所有對象的定義文件,比如dom,標簽等
const div:HTMLDivElement = document.createElement('div')
3.引入依賴
3.1. 引入模塊文件
引入模塊文件通常使用 import
import {A} from './a.ts'
const a:A ={name:'gg'}
3.2. 引入非模塊類的聲明文件
使用三斜線 reference 引入,有常用兩種方式 path和types
他們區別就是 types 一般引入外部依賴的聲明,path 一般引入自己寫的聲明
比如外部聲明文件位置為node_modules/@types/b/index.d.ts
,內容為type B={age:number}
,使用 path 和 types 引入方式如下:
/// <reference path="node_modules/@types/b/index.d.ts" />
/// <reference types="b" />
非模塊的聲明文件引入后為全局類型,可以直接使用
const b:B={age:100}
這兒可以看出,與js文件引入相比,ts多了一項尋址策略,它中會自動尋找node_modules/@types下的文件。
3. 聲明合並 官網地址
“聲明合並”是指編譯器將針對同一個名字的多個獨立聲明合並為單一聲明。 合並后的聲明同時擁有原先多個聲明的特性
常見的使用例子為擴展屬性
點擊查看代碼
interface C {
a:string
b:string
}
interface C {
c:string
}
const v:C = {a:'',b:'',c:''}
4. vite+vue3 工程中的常見配置
所有依賴插件,在官網中有詳細說明如何使用類型。
4.1 vite 注入的全局類型
vite注入了例如import.meta.env.BASE_URL
,在import.meta中不存env屬性,所以需要對ImportMeta
類型進行補充,
其文件位置在node_modules/vite/client.d.ts
。打開文件可以看到沒有使用export 或者import。所以其為非模塊聲明,引入需要用到:
/// <reference types="vite/client" />
4.2 vue注入類型
vue類型文件在node_modules/vue/dist/vue.d.ts
,打開后可以看到有export 和import關鍵字,所有必須使用import引入,
引入一次后可以在其它文件模塊文件使用類型。
import 'vue'
4.2.1 注冊全局組件
如果有注冊全局組件,就需要對全局組件進行類型擴展。
如下擴展一個Layout組件
點擊查看代碼
import 'vue' // 此處說明此文件是模塊文件
declare module 'vue' {
export interface GlobalComponents {
Layout: typeof import('./components/Layout.vue')['default']
}
}
4.2.2 注入.vue文件類型
當引入一個vue文件時,js編譯器可以通過,但是ts卻發現找不到。這是因為ts為.ts、.js、.tsx等文件已定義類型,vue文件需要手動定義類型
declare module '*.vue' {
import { DefineComponent } from 'vue'
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/ban-types
const component: DefineComponent<{}, {}, any>
export default component
}
4.2.3. 別名設置
在某些時候,路徑使用別名會很方便,比如將@
指向src
使用import data from '@/data'
訪問src/data.ts,由於ts與js是兩套系統,雖然js能夠正常運行,但ts並不知曉'@/data'路徑指向哪兒,所以需要在tsconfig.json中也配置路徑別名,需要配置compilerOptions.baseUrl與compilerOptions.paths
{
"compilerOptions": {
"baseUrl": "./",
"paths": {
"@/*":["src/*"]
},
}
}
此處地址轉換 @/data
=> ${baseUrl}src/data
=> ./src/data
尋找到了正確地址。
4.3 編輯器配置
使用vscode + volar
volar能夠自動按照tsconfig.json配置調用typescript做類型分析,不必將ts運行集成到項目中。也就是說類型系統由volar運行,js由項目本身運行。
5 vue3中api支持 官方文檔
接口api工具 json2ts
將json轉換成ts
遺留問題
在全局定義中 :declare let a:3
在其他文件中使用: let a = ''
不報錯原因:declare let a 解釋了一個全局的變量a 他的值是3,在模塊文件中可以再次定義,就如fn內部能定義一個外部作用域的變量。當直接使用 a = ''
時出現報錯