TS入门 | 青训营笔记

67 阅读3分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 4 天,加油!

TS

TS的发展与基本语法

与JS 的区别和优势

  • JS

    • 动态类型---执行的时候检查
    • 弱类型语言(类型转换)
  • TS

    • 静态类型---未执行的时候检查
    • 弱类型语言(类型转换)
  • 带来的好处

    • 可读性增强:基于语法解析TSDoc,ide增强
    • 可维护性增强:在编译阶段暴露大部分错误 --> 多人合作的大型项目中,获得更好的稳定性和开发效率
    • 包含兼容所有JS特性,支持共存
    • 支持渐进式引入与升级

基本语法

编写代码的变化:

  • 基本类型
// 字符串JS-TS
const q1 = 'string'
const q2: string = 'string'

// 数字JS-TS
const w1 = 1
const w2: number = 1

// 布尔值JS-TS
const e1 = true
const e2: boolean = true

// null JS-TS
const r1 = null
const r2: null = null

// undefined JS-TS
const t1 = undefined
const t2: undefined = undefined

console.log(q1, q2)
console.log(w1, w2)
console.log(e1, e2)
console.log(r1, r2)
console.log(t1, t2)

  • 对象类型
const bytedancer: IBytedancer = {
    jobId: 9301231,
    name: "Lin",
    sex: "man",
    age: 28,
    hobby: 'swimming'
}

interface IBytedancer {
    // 只读属性:约束属性不可在对象初始化外赋值
    readonly jobId: number
    name: string
    sex: 'man' | 'woman' | 'other'
    age: number
    // 可读属性:定义该属性可以不存在
    hobby?: string

    // 任意属性:约束所有对象属性都必须是该属性的子类型
    [key: string]: any
}

// 报错:无法分配到“jonId”,因为是只读属性
// bytedancer.jobId=13856

// 报错:缺少属性“name”,hobby可缺省
/*const bytedancer2: IBytedancer = {
    jobId: 4563,
    sex: 'woman',
    age: 15
}*/

// 成功:任意属性标注下可以添加任意属性
bytedancer.plateform = 'data'

  • 函数类型
function add1(x, y) {
   return x + y
}

const multi1 = (x, y) => x * y

console.log(multi1(2, 5))

interface IMulti {
   (x: number, y: number): number
}

const multi2: IMulti = (x, y) => x * y
console.log(multi2(2, 5))

function add2(x: number, y: number): number {
   return x + y
}

const multi3: (x: number, y: number) => number = (x, y) => x * y

console.log(multi3(2, 5))

  • 函数重载
// 对getDate函数进行重载,timestamp为可缺省参数
function getDate(type: 'string', timestamp?: string): string

interface IGetDate {
    (type: 'string', timestamp?: string): string

    (type: 'date', timestamp?: string): Date

    (type: 'string' | 'date', timestamp?: string): Date | string
}

// 不能将类型"(type:any,timestamp:any)=>string|Date"分配给类型“IGetDate”
// 不能将类型“string|Date”分配给类型“string”
// 不能将类型“Date”分配给类型“string
const getDate2: IGetDate = (type, timestamp) => {
    const date = new Date(timestamp)
    return type === 'string' ? date.toLocaleString() : date
}
  • 数组类型
// 类型+方括号
type IArr1 = number[]

// 泛型
type IArr2 = Array<string | number | Record<string, number>>

// 元组
type IArr3 = [number, number, string, string]

// 接口
interface IArr4 {
    [key: number]: any
}

const arr1: IArr1 = [1, 2, 3, 4, 5, 6]

const arr2: IArr2 = [1, 2, '3', '4', {a: 1}]

const arr3: IArr3 = [1, 2, '3', '4']

const arr4: IArr4 = ['string', () => null, {}, []]
  • 补充类型
// 空类型 表示无赋值
type IEmptyFunction = () => void

// 任意类型,是所有类型的子类型
type IAnyType = any

// 枚举类型:支持枚举值到枚举名的正、反向映射
enum EnumExample {
    add = '+',
    multi = '*'
}

console.log(EnumExample['add'] === '+')

console.log(EnumExample['+'] === 'add')

enum EColor {Mon, Tue, Wed, Thu, Fri, Sat, Sun}

console.log(EColor['Mon'] === 0)

console.log(EColor[0] === 'Mon')

// 泛型
type INumber = Array<number>

  • 泛型

function getRepeatArr(target) {
    return new Array(100).fill(target)
}

type IGetRepeatArr = (target: any) => any[]

type IGetRepeatArrR = <T>(target: T) => T[]

// 泛型接口&多泛型
interface IX<T, U> {
    key: T
    val: U
}

// 泛型类
class IMan<T> {
    instance: T
}

// 泛型别名
type ITypeArr<T> = Array<T>
  • 泛型:不预先指定具体的类型,而在使用的时候再指定类型的一种特性

    • 泛型约束
    • 泛型参数默认类型
  • 类型别名 & 类型断言

  • 字符串/数字 字面量