目錄
前言
文件太無趣,我們就來講個故事嘗試著貫穿ts的知識點吧。
part1-講個故事
從前有座山,山裡有座廟,據說還有隻大腦腐,還有一些其他什麼的
interface IMountain{
temple: Temple // 寺廟
tiger?: Tiger // 腦腐
[other: string]: any // 有點其他什麼的
}
複製程式碼
廟裡有個老方丈和很多個小和尚,養了一些雞啊鴨啊(就不說還有其他什麼的)
interface ITemple {
holder: Holder // 老住持
monk: Monck[] // 小和尚
poultry: (ChickeC | Duck)[] // 雞鴨
}
複製程式碼
描述完了之後我們開始實現
// 腦腐、鴨子、雞、人都屬於動物,我們建個虛擬基類,不讓他例項化。
abstract class Animal{
mouse = 1 // 一張嘴
leg = 2 // 兩條腿
protected voice(content:string){ console.log(content) }
}
// 鴨子是呱呱叫
class Duck extends Animal{
quack(){ this.voice('quack') }
}
// 雞是咯咯噠
class Chicke extends Animal{
crow(){ this.voice('gegeda') }
}
// 腦腐是嗷嗚而且是四條腿
class Tiger extends Animal{
leg = 4
howl(){ this.voice('howl') }
}
複製程式碼
我靈機一動想讓他變成一隻強雞建議閱讀順序1、2、3、4
// 3、定義一個建構函式型別,一下兩者都可以
type ConstructorFuc<T> = new (...arg:any[])=>T;
interface IConstructorFuc<T>{
new (...arg:any[]):T;
}
// 4、這個是雞特有的屬性
interface IChicke{
crow():void
};
// 2、構建這個裝飾器,裝飾器接收一個建構函式作為方法,定義返回型別是雞。
const strong = (ctor:ConstructorFuc<Animal & IChicke>)=>{
return class extends ctor{
crow(){
super.crow();
super.crow();
}
}
}
// 1、這裡用裝飾器加強雞
@strong
class Chicke extends Animal{
crow(){ this.voice('gegeda') }
}
複製程式碼
下面我們來讓他展示下自己吧
const tiger = new Tiger();
tiger.howl()// howl
const duck = new Duck();
duck.quack()// quack
const chicke = new Chicke();
chicke.crow();// gegeda gegeda
複製程式碼
可以看到雞比較牛皮,叫了兩聲。
下面我們來建立人物,給他多新增姓名這個屬性,發出聲音的方式就是speak了。
interface IPeople{
name: string
speak(content: string):void
}
複製程式碼
接下來是小和尚,小和尚難免會有個小祕密,一般不會輕易被人知道,但是總得有讓人知道的方法。
class Monck extends AbsAnimal{
name: string;
private secret = '講出自己的小祕密';
speackSecret(){
this.speak(this.secret);
}
constructor(param: Pick<IPeople, 'name'>){
super();
this.name = param.name;
}
speak(content:string){
super.voice(`${this.name}:${content}`)
}
}
複製程式碼
眾所周知,住持同學需要由小和尚成長而來,作為住持同學,可以命令小和尚做自己能完成的事情,而且自己的名稱上冠上一個title。
class Holder extends Monck{
constructor(param: Pick<IPeople, 'name'>){
super(param);
this.name = param.name+`(住持)`;
}
command(monck:Monck, something: keyof Monck){
if(typeof monck[something] === 'function'){
console.log(`${this.name} 命令 ${monck.name} 去幹 ${something}`);
(monck[something] as Function)();
}
console.log(`${monck.name} 幹不了 ${something}`);
}
}
複製程式碼
接下來,方丈同學要求小和尚說出自己的祕密
const holder = new Holder({ name: '鳩摩智' });
const monck = new Monck({ name: '虛竹'});
holder.command(monck, 'speackSecret');
// 鳩摩智(住持) 命令 虛竹 去幹 speackSecret
// 虛竹:講出自己的小祕密
複製程式碼
我們讓他們都住進寺廟裡
const temple:ITemple = {
holder,
monks:[monk],
poultry: [duck, chicke]
}
複製程式碼
寺廟放進山裡,並有一隻來去自如的腦腐
const isTigerMountain = (mountain: IMountain)=>{
console.log(`這${mountain.tiger ? '是' : '不是'}一座腦腐山`)
}
const mountain: IMountain = {
temple
}
isTigerMountain(mountain);
mountain.tiger = tiger;
isTigerMountain(mountain);
Array().fill(6).forEach(data=>{
(mountain.tiger as Tiger).howl()// aowu * 6
})
mountain.tiger = undefined;
isTigerMountain(mountain);
複製程式碼
part2-d.ts檔案
d.ts
,declare
檔案,定義檔案,裡面內容只能包含一些定義,主要用法有以下。
- 宣告單個 js 檔案
當 ts 需要引入 js 相關檔案時,比如我有一個js檔案,引入會報錯
// speak.js
export const leeSpeak = (word)=>{
console.log(word);
};
// other.js
import speck from './speak';// Could not find a declaration file for module './speak'.
speck.leeSpeak();
複製程式碼
解決方式是在speck.js
同級目錄下新建一個同名的d.ts檔案:
// speck.js
export const leeSpeak: (word:string)=>void;
複製程式碼
這種方式有個問題就是,在執行 tsc 時,js檔案不會匯出到dist相關目錄( 在webpack下沒關係 )。
當然你也可以啟動 allowjs,但是不要開checkjs,因為js無法進行型別定義,而checkjs會按照ts進行語法檢查,如果正常的js語法不能被編譯器推斷容易產生報錯。
- 全域性宣告變數 / 型別
編碼過程中我們們可能通過1、 webpack 的 externals屬性 或者 webpackDllPlugin 引入一些包;2、 DefinePlugin 定義一些變數;3、node_module 中 @types 資料夾下沒有相應生命檔案包;為了讓他們能夠正常使用,我們需要定義相應的型別。
// webpack.base.js
new DefinePlugin({
"CURRENT_ENV": 'test'
})
// xx.d.ts
declare namespace lee{
const name: string
}
declare module 'zhang'{
const name: string
}
declare const CURRENT_ENV : 'test'
// xx.js
import zhang from 'zhang';
zhang.name
lee.name
CURRENT_ENV
複製程式碼
全域性包宣告不能使用 export、import 進行模組引入和匯出。
ps: 我們們編碼的過程中我們們還會遇到一種情況,就是 node_modules @types 下有相應的模組化宣告檔案,但是我們想置於全域性,舉例react。
// 通常情況下使用react
// 但是所有頁面都引入不免有些麻煩
import React from 'react';
// global.d.ts
declare global{
const React: typeof import("react");
}
export {}
複製程式碼
typescript的一些常見問題就說到這裡啦。