# TypeScript 基础

# 强弱类型

强类型 不允许改变变量的数据类型,除非进行强制类型转换 若类型 可以随时改变变量的数据类型

# 动静类型

动态类型 在运行阶段确定所有变量的类型 静态类型 在编译阶段确定所有变量的类型

# 接口

# 对象类型接口

鸭子类型检查

interface List {
    id: number;
    name: string;
}

interface Duck {
    data: List[]
}

function test(result: Duck) {
    console.log(result.data[0])
}

const res = {
    data: [
        { id: 1, name: 'a', age: 8 }
    ]
}

test(res) //这样子是允许的 虽然List的数据定义里面未包含age
test({
    data: [
        { id: 1, name: 'a', age: 8 }
    ]
})  //直接传入对象自变量是不允许的

解决方案:

1.使用as
test({
    data: [
        { id: 1, name: 'a'},
        { id: 2, name: 'a', age: 123}
    ]
} as Duck)

但是这样子也会报错
test({
    data: [
        { id: 1, name: 'a', age: 456},
        { id: 2, name: 'a', age: 123}
    ]
} as Duck)

2.使用<>
test(<Duck>{
    data: [
        { id: 1, name: 'a'},
        { id: 2, name: 'a', age: 123}
    ]
})
同样的两个写满也会报错
test(<Duck>{
    data: [
        { id: 1, name: 'a', age: 456},
        { id: 2, name: 'a', age: 123}
    ]
})

3.使用字符串索引签名,增加多个属性的支持
interface List {
    id: number;
    name: string;
    [x:string] : any;
}

# 函数类型接口

如何定义一个函数接口

//1. 定义变量 let add: (x: number, y: number) => number

//2. 使用接口 interface Add { (x: number, y: number): number }

//3. 使用 type type Add = (x: number, y: number) => number

如何定义一个混合类型的接口

interface Lib { (): void; <== 函数 version: string; <== 属性 doSomething(): void; <== 函数 }

//4.直接定义函数 ts 会做返回值参数类型推断 function add(x: number, y: number) { return x + y; }

ts 直接显示声明函数返回值类型 function add(x: number, y: number): number { return x + y; }

# 类型推断

不需要指定变量的类型,TypeScript 可以根据某些规则自动的,为其推断出一个类型

  • 基础类型推断
  • 最佳通用类型推断
  • 上下文类型推断

# 类型兼容

结构之间兼容,成员少的兼容成员多的(成员少的可以赋给成员多的) 函数之间兼容,参数多的兼容参数少的(参数多的可以赋给参数少的)

# 类型保护

  • type of
  • instanceof
  • in
  • 类型保护函数

# 索引类型

// keyof T
let obj = {
    a: 1,
    b: 2,
    c: 3
}

function getValues<T, K extends keyof T>(obj: T, keys: K[]): T[K][] {
    return keys.map(key => obj[key])
}

console.log(getValues(obj, ['a', 'b']))
console.log(getValues(obj, ['e', 'c']))

# Babel or TSC

在Babel中无法编译的问题

1. namespace
namespace N {
    export const n = 1;
}

2. 声明
let s = {} as A
s.a = 1

3.常量枚举
const enum E { A }

4.默认导出
export = 

建议:

  • 如果没有使用babel,首选TypeScript自身的编译器(可配合ts-loader使用)
  • 如果项目中已经使用了Babel,安装@babel/preset-typescript(可配合tsc做类型检查)
  • 两种编译工具不要混用

# Eslint

RoadMap: TSLint -> ESLint #4534 https://github.com/palantir/tslint/issues/4534

# 测试

ts系 编译工具: ts-loader 代码检查工具: eslint-typescript-eslint 单元测试工具: ts-jest

babel系 编译工具: @babel/preset-typescript 代码检查工具: babel-eslint 单元测试工具: babel-jest

陕ICP备20004732号-3