typescript + react 项目开发体验之typescript

栏目: IOS · Android · 发布时间: 5年前

内容简介:从前有座山,山里有座庙,据说还有只大脑腐,还有一些其他什么的庙里有个老方丈和很多个小和尚,养了一些鸡啊鸭啊(就不说还有其他什么的)描述完了之后我们开始实现

从前有座山,山里有座庙,据说还有只大脑腐,还有一些其他什么的

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.tsdeclare 文件,定义文件,里面内容只能包含一些定义,主要用法有以下。

  1. 声明单个 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. 全局声明变量 / 类型

编码过程中咱们可能通过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的一些常见问题就说到这里啦。


以上所述就是小编给大家介绍的《typescript + react 项目开发体验之typescript》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

PHP与MySQL权威指南

PHP与MySQL权威指南

吴津津、田睿、李云、刘昊 / 机械工业出版社华章公司 / 2011-10 / 118.00元

PHPChina官方出品,Discuz!创始人戴志康、UCHome创始人李国德、ThinkPHP创始人刘晨、PHPCMS项目负责人王参加等联袂推荐。 本书是目前为止最全面的关于PHP与MySQL开发技术的书籍之一,系统而全面地讲解了PHP与MySQL技术的方方面面,适合初中级的PHP程序员系统地学习;本书也是目前为止首本系统而深入地讲解UCenter、Discuz!、UCHome、ShopN......一起来看看 《PHP与MySQL权威指南》 这本书的介绍吧!

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

在线进制转换器
在线进制转换器

各进制数互转换器

html转js在线工具
html转js在线工具

html转js在线工具