TypeScript|TypeScript 快速上手 —《基础语法篇》笔记

【TypeScript|TypeScript 快速上手 —《基础语法篇》笔记】本篇内容不涉及TypeScript安装以及配置,只涉及TypeScript语法相关内容。不讲废话,简单直接。
1、原始类型

const a: string = 'foo' const b: number = 100 const c: boolean = true const d: void = undefined const e: null = null const f: undefined = undefined const g: symbol = Symlol()

2、object 类型
object并不单指对象,而是指除了原始类型以外的其他类型
const foo: object = function () {} // [] // {} const obj: { foo: number,bar: string } = { foo: 123, bar: 'string' }

3、数组类型
// 第一种定义方式,元素类型设置为 *number* const arr1: Array = [1, 2, 3] // 第二种定义方式,较为常见 const arr2: number[] = [1, 2, 3]// 例子 function sum (...args: number[]) { // 传统做法是要判断传入的参数是否是数字, 而TypeScript中只需要像上面这样对参数做一个类型注解,就行了 return args.reduce(prev, current) => prev + current, 0) }sum(1, 2, 3, 'foo') // 这里传入了一个非数字的值就会报错

4、元组类型
元组就是一个明确元素数量明确元素类型 的数组
const tuple: [number, string] = [18, 'foo'] // const tuple: [number, string] = [18, 18] 类型不匹配,会报错 // const tuple: [number, string] = [18, 'foo', 'xxx'] 数量不匹配,会报错// 访问 const age = tuple[0] const name = tuple[1]// 解构 const [age, name] = tuple

5、enum 类型
// enum 对象的属性可以不用赋值,默认从0开始递增, 也可以赋值Draft = 5,后面的就从5开始递增 也可以给具体的值,比如 Draft = 'xxx',这样后面的属性都要给具体的值 enum PostStatus { Draft = 0, Unpublished = 1, Published = 2 }const post = { title: 'Hello TypeScript', content: 'TypeScript is a typed superset of JavaScript.', status: PostStatus.Draft // 0 // 1 // 2 }

6、函数类型
// 声明式函数 // 参数a和b是number类型,函数返回是string类型, // 参数后带问号代表是可选参数 // 当参数数量不固定的时候可以使用rest运算符来接受参数,类型是一个值为number的数组 function func1 (a: number, b?: number, ...rest: number[]): string { return 'func1' }// 函数表达式定义函数 const func2 = function (a: number, b: number): string { return 'func2' }// 如果把一个函数作为参数传递,类似callback函数。 function fntD(callback: (bl: boolean) => boolean) { callback(true) } function callback(bl: boolean): boolean { console.log(bl) return bl } const dResult = fntD(callback)

7、任意类型 any
// value 可以接受任意类型 function stringfy (value: any) { return JSON.stringify(value) }stringify('string') stringify(10) stringify(true)// foo 可以任意赋值 let foo: any = 'string' foo = 100

8、隐式类型推断
// age 赋值为 number 类型 let age = 18 // numberage = 'string' // 会警告错误,因为age是number类型let foo // 没有赋值,就是any类型foo = 100 foo = 'string'

9、类型断言 as
// 假定这个 nums 来自一个明确的接口 const nums = [110, 120, 119, 112]// 这里TypeScript推断res的类型为 number|undefined // 因为它并不知道这个i到底在数组中有没有 const res = nums.find(i => i > 0)// 这里就会报错警告 const square = res * res// 如果我们直接 断言 这个 res 就是 number 类型 const num1 = res as number// 这里就不会报错了 const square = res * res

10、接口 interface
接口用来约定对象的结构,一个对象要实现一个接口,就必须拥有这个接口中所包含的所有成员
interface Post { title: string content: string }function printPost (post: Post) { console.log(post.title) console.log(post.content) }printPost({ title: 'Hello TypeScript', content: 'A JavaScript superset' })// 特殊的接口成员 可选成员 只读成员 interface Post{ title: string content: string subtitle?: string // 加问号就是可选成员 readonly summary: string // 加 readonly 就是只读成员 }const hello: Post = { title: 'Hello TypeScript', content: 'A javascript superset', summary: 'a javascript' }hello.summary = 'other' // 会报错,因为 summary 是只读成员// 动态成员 interface Cache { [prop: string]: string }const cache: Cache = {}cache.foo = 'value1' cache.bar = 'value2'

11、类 Class
Class Person { // 在这里赋值,和在构造函数中初始化必须两者选其一 name: string // = 'init name' 这里可以直接初始化 private age: number // 这里定义 age 为私有属性 protected gender: boolean // 受保护的类型 readonly national: string // 只读属性,一经初始化,不可更改constructor (name: string, age: number) { // 需要在上面标注出构造函数中属性的类型 this.name = name this.age = age this.gender = true this.national = national }sayHi (msg: string): void { console.log(`I am ${this.name}, ${msg}`) console.log(this.age) } }const tom = new Person('tom', 18) console.log(tom.name) // tom console.log(tom.age) // 报错,因为 age 是私有属性,所以访问不到 console.log(tom.gender) // 报错,因为 gender 是受保护的属性,这里访问不到// 在下方新声明一个类 student 继承与 Person class Student extends Person { constructor (name: string, age: number) { super(name, age) console.log(this.gender) // 这里就一个访问到 受保护的属性 gender }

12、类与接口 implements 实现
interface Eat { eat (food: string): void }interface Run { run (distance: number): void }// Person类,实现了 Eat 和 Run 两个接口 class Person implements Eat, Run { eat (food: string): void { console.log(`优雅的进餐:${food}`) }run (distance: number) { console.log(`直立行走:${distance}`) } }// Animal类,实现了 Eat 和 Run 两个接口 class Animal implements Eat, Run { eat (food: string): void { console.log(`饥不择食的吃:${food}`) }run (distance: number) { console.log(`爬行:${distance}`) } }

13、抽象类
abstract 定义抽象类,抽象类只能被继承,不能通过 new 的方式创建实例对象
// 定义一个抽象类 Animal abstract class Animal { eat (food: string): void { console.log(`饥不择食的吃:${food}`) }// 定义一个抽象方法 run,可以不需要方法体。 // 定义了抽象方法之后,子类中必须实现这个抽象方法 abstract run (distance: number): void }class Dog extends Animal { run(distance: number): void { console.log('四脚爬行', distance) } }const d = new Dog() d.eat('嘎嘎') // 饥不择食的吃:嘎嘎 d.run(100) // 四脚爬行 100

14、泛型 Generics
泛型是指在定义接口函数类的时候,没有指定具体的类型,等到我们在使用的时候再去指定具体的类型的这种特征
// 这里声明一个创建 number 类型数组的函数 creatNumberArray function createNumberArray (length: number, value: number): number[] { // 这里的Array是 any 类型,所以要给它指定一个 Number 类型 const arr = Array(length).fill(value) return arr }// 这里声明一个创建 String 类型数组的函数 createStringArray function createStringArray (length: number, value: string): string[] { const arr = Array(length).fill(value) return arr }// 因为上面的两个函数代码有冗余,所以这里我们可以使用 泛型 // 一般我们使用 T 来作为泛型参数的名称,然后把函数中不明确的类型都改为 T 来做代表 function createArray (length: number, value: T): T[] { const arr = Array(length).fill(value) return arr }// 然后使用泛型的时候 传递 T 的类型 const res = creatArray(3,'foo')// const res = createNumberArray(3, 100) // res => [100, 100, 100]

基础语法篇到这里结束,更多关于TypeScript的使用请关注我,持续为大家更新。

    推荐阅读