TypeScript 笔记

95 阅读3分钟

` const a:number = 1

const b:string = 'b'

const c:boolean = true

const d: null = null

const e: undefined = undefined

const f:symbol = Symbol()

const g: Array = [1]

const h: number[] = [1]

const i: { foo: number } = { foo: 1 }

const j: [number, string] = [1, 'sd']

// 编译后,为双向键值对 // enum Sexs { // nan = 0, // nv = 1 // }

// 编译后,去去掉该枚举,post中的sex会变成0,nan会显示在后面的注释中 const enum Sexs { nan = 0, nv = 1 }

const post = { name: '张三', sex: Sexs.nan }

// 函数声明 function fn1 (a: number, b: number = 10): number { return a+b }

// 函数表达式 const k: (a: number, b: number) => string = function (a: number, b: number): string { return a+ b + '' }

// 任意类型 function fn2 (a: any):any { return a } // fn2('s')

// 若是定义一个变量时,未进行类型声明,typeScript会根据所附的值隐性类型推断当前变量类型,若未赋值,则推断为any,

let l = 1 // l = 'ss' fail // l = 2 success

let m // m = 'ss' success // m = 2 success

// 断言 typeScript 在某些时候,推断出来的类型不准确,此时需要断言(断定的给出更准确的答案)为其定义更加准确的类型

const temp = [100, 200, 300, 400] const n = temp.find(i => i > 0) // 推断的n类型为undefined | number const o = n as number // 这两种方式实现断言 const p = n // 该方式不能在jsx中使用,因为<>会与jsx中的<>冲突

// 接口 interface 用来约束对象类型的结构,在实际中,并没有任何意义 interface Post { name: string // 可以使用,或者; 或者不使用任何符号进行分割 age: number }

function fn3(post: Post) { console.log(post.age) console.log(post.name) }

/**

  • interface 补充
  • interface-1.是否有
  • interface-2. 只读
  • interface-3.动态属性 */

// interface-1 interface Interface1 { isHas?: number // 实际上为 isHas?: number | undefined }

// interface-2 interface Interface2 { readonly isReadonly: number }

// interface-3 interface Interface3 { [key: string]: number // key为一个代替名字,可以使用任何值, string规定属性名的类型,number为值的类型 }

// class基础使用 class Person { public name: string protected age: number constructor(name: string, age: number) { this.name = name this.age = age } sayHi(arr: string): void { console.log(name: ${this.name}, age: ${this.age}, arr: ${arr});

}

}

/**

  • class 修饰符
  • public 公开的
  • private 私有的,外部不能访问,包括子类
  • protected 受保护的 外部不能访问,子类可以访问
  • ** 若构造函数是私有的,那么可以在class内部用静态方法去创建一个类 */

/**

  • class readonly
  • readonly 和修饰符一起使用的时候,跟在修饰符之后
  • 初始化赋值readonly属性 在构造函数中/在声明的时候 二者选其一,并且初始化之后,不能在修改其值了 */

/**

  • class 与 interface 的配合
  • interface 可以约定 class 所具有的成员, 但是不会去限制其的实现 */

interface EatAndRun { eat (food: string): void run (addres: string): void }

class Person1 implements EatAndRun { eat (food: string): void { console.log(person, ${food}); } run (addres: string): void { console.log(person, ${addres}); } }

class Dog1 implements EatAndRun { eat (food: string): void { console.log(person, ${food}); } run (addres: string): void { console.log(person, ${addres}); } }

// new Person1().eat('a')

interface Eat { eat (food: string): void }

interface Run { run (addres: string): void }

class Person2 implements Eat,Run { eat (food: string): void { console.log(person, ${food}); } run (addres: string): void { console.log(person, ${addres}); } }

class Do2 implements Eat { eat (food: string): void { console.log(person, ${food}); } run (addres: string): void { console.log(person, ${addres}); } }

/**

  • 抽象 abstract
  • 抽象类 限制 类的统一行为
  • 抽象类不能被new实例化
  • 抽象类中的抽象方法,不用写起具体实现,但在子类中必须进行重写 */

abstract class Animal { eat(food: string): void{ console.log('吃'); } abstract run(add: string): void } class Dog extends Animal { run(add: string): void { console.log(add);
} }

/**

  • 泛型 用来解决定义时,不确定类型,只有在使用的时候才能确定类型,所以把类型作为泛型参数传进来进行使用。
  • 基本都是用T来代表泛型参数 */

// 创建一个指定长度,指定元素的数组 // 数字 function createNumberArray (length: number, value: number): number[] { return new Array(length).fill(value) } // 字符串 function createStringArray (length: number, value: string): string[] { return new Array(length).fill(value) } // 通用,其中类型作为泛型参数传进来使用 function createArray (length: number, value: T): T[] { return new Array(length).fill(value) }

/**

  • 类型声明 declare
  • 在使用第三方npm依赖的时候,其中某些成员可能没有就行typescript类型声明,此时可以去安装对应依赖包的typescript声明模块
  • eg: lodash, 一般typescript模块都是(@type/模块)格式,例如 @type/lodash
  • 若是没有对应模块,可以利用declare 对其声明一个typescript类型
  • eg: declare function a(str: string): string */`