TYPESCRIPT采坑-手记

(跟新中。。。)

1.通过TS检测的万金油

let a as unknown as any
//嵌套函数 即函数内命名函数及调用,TS检测不到
const fn: (a: string[], cb: () => void ) => nerver = function(){
    const annoy = function(){};// annoy就会逃脱TS的类型检测,因为TS属于结构类型系统,并不知道这个函数什么时候执行,所以也就不知道函数内部的实现
}

2 有趣的可联合辨识

即把一些具有相同结构和不同结构成员的数据类型通过联合|组成的联合类型;

那个相同的结构属性称做 可辨识的特征或 标签

interface Square {
    kind: "square";
    size: number;
}
interface Rectangle {
    kind: "rectangle";
    width: number;
    height: number;
}
interface Circle {
    kind: "circle";
    radius: number;
}
// kind就是可辨识的联合特征
type Shape = Square | Rectangle | Circle;
function test(area:  Square | Rectangle | Circle) {
  if (area.kind === 'circle') {//(property) kind: "square" | "rectangle" | "circle"
    return '3';
  }
}

3.索引类型(Index types)

用法: 声明一个泛型T,一个泛型K extends keyof T,表示的就是K属于T的keys值的联合类型;T[K]就表示对应的成员K的类型

4.映射类型

旨在从旧的数据类型中生成新的数据类型,例如将成员改为只读或者可选属性

type Readonly<T> = {
    readonly [P in keyof T]: T[P];
}
type Partial<T> = {
    [P in keyof T]?: T[P];
}
type Pick<T, K extends keyof T> = {
    [P in K]: T[P];
}
type Record<K extends string, T> = {
    [P in K]: T;
}
Exclude<T, U> -- 从T中剔除可以赋值给U的类型。
Extract<T, U> -- 提取T中可以赋值给U的类型。
NonNullable<T> -- 从T中剔除null和undefined。
ReturnType<T> -- 获取函数返回值类型。
InstanceType<T> -- 获取构造函数类型的实例类型。

5.在使用模块(外部模块)与命名空间(内部模块)的时候需要注意避免以下情况

  • 文件的顶层声明是export namespace Foo { ... } (删除Foo并把所有内容向上层移动一层)
  • 文件只有一个export classexport function (考虑使用export default
  • 多个文件的顶层具有同样的export namespace Foo { (不要以为这些会合并到一个Foo中!)

6.ts.config.json配置值讲解之一二

compileOnSave:是否在保存之后进行编译检查

baseUrl:项目的根路径,index.html里的会被命令行中的覆盖。

ouDir:输入路径

allowJs:是否允许js文件

moduleResolution: node或者classic模块解析方法

jsx:是否允许jsx语法 react

path:一些特殊的依赖模块的路径放置地,即对符合左边规则的一些依赖模块,会按照右侧的路径去寻找

rootDirs:相对虚拟路径,即在这里的路径下的文件会被合并到同一个目录下,即拥有同一个相对父路径。

7.巧用namespace

在es5中,如果我们定义了一个函数,如果要对函数进行扩展,那我们只能直接赋值操作,例如函数的静态方法,下面是es5的写法,我们重定了函数的name属性

var fn = (function a (Main){
    Main.name = 'fn';
}(function (){}))

在TS中我们可以巧用namespace的合并实现

function fn(){console.log(fn.name)}
namespace fn{
    export const name = 'fn';// 我们必须导出这个,才能够访问的到他
}

 编译后的代码,可以看出和上面的写法基本一致

function fn() { console.log(fn.name); }
(function (fn) {
    fn.name = 'fn';
})(fn || (fn = {}));

 注意:类与类与变量无法合并

8.TS与React的结合

启用jsx,后缀名修改为.tsx 

9, 注意装饰器的执行阶段--发生在声明阶段之后,而不是类实例化的时候。

function f() {
    console.log(1);
    return function(...a) {
      console.log(a, 2);
    };
  }
  @f()
  class Test {
    ss = '';
    @f()
    test() {
      console.log(4);
    }
    constructor() {
      this.ss = 'er';
    }
  }

看编译过之后的代码,其中_decorate和_metadata是TS库内的函数,目的是添加装饰器到目标上的,源码很简单,大家谷歌看一下就可以了

/**
 * @return {?}
 */
function f() {
    console.log(1);
    return (/**
     * @param {...?} a
     * @return {?}
     */
    function (...a) {
        console.log(a, 2);
    });
}
let Test = class Test {
    constructor() {
        this.ss = '';
        this.ss = 'er';
    }
    /**
     * @return {?}
     */
    test() {
        console.log(4);
    }
};
__decorate([
    f(),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", void 0)
], Test.prototype, "test", null);
Test = __decorate([
    f(),
    __metadata("design:paramtypes", [])
], Test);

可以看到,f装饰的执行阶段就在class声明之后,优先class内部的方法,属性再之后是class自身

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值