文档太无趣,咱们就来说个故事尝试着贯穿ts的知识点吧。node
从前有座山,山里有座庙,听说还有只大脑腐,还有一些其余什么的react
interface IMountain{
temple: Temple // 寺庙
tiger?: Tiger // 脑腐
[other: string]: any // 有点其余什么的
}
复制代码
庙里有个老方丈和不少个小和尚,养了一些鸡啊鸭啊(就不说还有其余什么的)webpack
interface ITemple {
holder: Holder // 老住持
monk: Monck[] // 小和尚
poultry: (ChickeC | Duck)[] // 鸡鸭
}
复制代码
描述完了以后咱们开始实现web
// 脑腐、鸭子、鸡、人都属于动物,咱们建个虚拟基类,不让他实例化。
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') }
}
复制代码
我灵机一动想让他变成一只强鸡建议阅读顺序一、二、三、4typescript
// 三、定义一个构造函数类型,一下二者均可以
type ConstructorFuc<T> = new (...arg:any[])=>T;
interface IConstructorFuc<T>{
new (...arg:any[]):T;
}
// 四、这个是鸡特有的属性
interface IChicke{
crow():void
};
// 二、构建这个装饰器,装饰器接收一个构造函数做为方法,定义返回类型是鸡。
const strong = (ctor:ConstructorFuc<Animal & IChicke>)=>{
return class extends ctor{
crow(){
super.crow();
super.crow();
}
}
}
// 一、这里用装饰器增强鸡
@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了。post
interface IPeople{
name: string
speak(content: string):void
}
复制代码
接下来是小和尚,小和尚不免会有个小秘密,通常不会轻易被人知道,可是总得有让人知道的方法。ui
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。this
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);
复制代码
d.ts
,declare
文件,定义文件,里面内容只能包含一些定义,主要用法有如下。
当 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语法不能被编译器推断容易产生报错。
编码过程当中我们可能经过一、 webpack 的 externals属性 或者 webpackDllPlugin 引入一些包;二、 DefinePlugin 定义一些变量;三、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的一些常见问题就说到这里啦。