TypeScript 学习小结

如何引入并正确执行TS

1、当前浏览器是不认识TS的,需要转化为js
2、使用webpack的 ts-loader
3、必须创建tsconfig.json文件,并做对应配置

{
    "compilerOptions": {
      "target": "es5",
      "module": "commonjs",
      "strict": true
    }
}

typeScript支持的类型

1、javascript支持的类型
string
number
bolean
null
undefined
symbol
bigint
object: Array Date

2、自有类型

any

1)、可以赋值任何类型变量

let a: any
a = 1
a = false
a = '2'

2)、可以赋值给任意类型的变量 最好不要使用

let b: string
b = a
unknow

1)、可以赋值任何类型变量

let a: unknow
a = 1
a = false
a = '2'

2)、不可以赋值给任意类型的变量

let b: string
b = a // 报错

3)、赋值给其它变量时,需要提前声明确认当前类型

// 第一种
if (typeof a === 'string') {
    b = a
}

// 第二种 不安全
b = a as string

// 第三种 不安全
b = <string>a

4)、就算当前赋值是字符串也不能使用 .toUpperCase() 方法,需要使用3

never 几乎不会用到

1)、不要用于定义变量
2)、TS自己推断值类型
3)、特殊中断函数的返回值,即函数不可能执行完成

function fn(): never {
    throw new Error('中断')
}
void

1)、用于定义函数返回值
2)、函数返回值为undefined或没有return,即没有返回值

function fn(): void {
    
}

function fn(): void {
    return undefined
}

function fn(): void {
    return
}

3)、不能使用函数的返回值去做其他逻辑

let result = function fn(): void {
    return undefined
}

<!-- 报错 -->
if (result) {

}
object

1)、非基础类型都可以

Object

1)除了 null、undefined 其余都可以赋值

声明对象
<!-- 属性必须是指定类型、属性数量不能多也不能少 -->
let person: { name: string, age: number }

person = {
    name: 'jack',
    age: 12
}
<!-- 使用 ?: 表示当前属性非必要 -->
let person: { name: string, age?: number }

person = {
    name: 'jack'
}
<!-- [key: string]: any 可以添加未定义的属性, 此时 获取 未定义的属性 也不会报错,返回undefined -->
let person: { name: string, age?: number, [key: string]: any }

person = {
    name: 'jack',
    hobby: '篮球'
}

console.log(person.a)

声明函数
let count: (a: number, b: number) => number

count = function(a, b) {
    return a + b
}
声明数组
let arr1: string[] = []
let arr2: Array<number> = []

arr1.push('12')
arr2.push(12)
tuple 元组,一种特殊的数组类型,不是关键字
<!-- 数组必须是两个元素,第一个是数字,第二个是字符串 -->
let arr1: [number, string]
<!-- 数组最多2个元素,第一个是数字,第二个是布尔类型,第二个可以不写 -->
let arr2: [number, boolean?]
<!-- 数组至少有一个元素,最大不限制,且第一个必须是数字,其他元素必须是字符串 -->
<!-- 这种写法只能, 只能包含一个 ...rest -->
let arr3: [number, ...string[]]

arr1 = [1, '2']
arr2 = [1]
arr1 = [1, '2', '3', '4']
enum 枚举

1)、数字枚举

<!-- 不指定数字时,默认从0开始顺序赋值 -->
enum Direction {
    Up,
    Down,
    Left,
    Right
}

<!-- 可以指定,如下面,Left6开始 -->
enum Direction {
    Up = 3,
    Down = 5,
    Left,
    Right
}

<!-- 但不要间隔赋值,且没有留足够自增值给中间的key,如下面,Left也是6,就重复了 -->
enum Direction {
    Up = 3,
    Down = 5,
    Left,
    Right = 6
}

function go(data: Direction) {
    switch (data) {
        case Direction.Up:
            console.log('向上')
            break;
        case Direction.Down:
            console.log('向下')
            break;
        case Direction.Left:
            console.log('向左')
            break;
        case Direction.Right:
            console.log('向右')
            break;
        default:
            console.log('停留')
            break;
    }
}

console.log(Direction)
// {0: 'Up', 1: 'Down', 2: 'Left', 3: 'Right', Up: 0, Down: 1, Left: 2, Right: 3}

go(Direction.Down)
go(Direction.Left)

2)、字符串枚举

<!-- 每个有特定值,没有反向枚举 -->
enum Direction {
    Up = 'up',
    Down = 'down',
    Left = 'left',
    Right = 'right'
}

console.log(Direction)
// {Up: 'up', Down: 'down', Left: 'left', Right: 'right'}

3)、常量枚举

const enum Direction {
    Up = 'up',
    Down = 'down',
    Left = 'left',
    Right = 'right'
}

<!-- 编译简化,去除未使用的值 -->
<!-- 不能直接打印 Direction -->
console.log(Direction.Up)
type 定义类型
type Age = number

let age: Age
type Time = number | string

let time: Time

time = '2024-12-31 12:12:12'
time = Date.now()
type Kitchen = {
    gasStove: number;
    knife: number;
    clean: boolean;
}

type Bedroom = {
    bed: number;
    closet: number;
}

type Room = Kitchen & Bedroom

let room: Room

room = {
    gasStove: 1,
    knife: 2,
    clean: true,
    bed: 1,
    closet: 2
}
type Fun = () => void

let fn1: Fun

<!-- 虽然返回值定义为 void, 但依然可以返回任意类型 -->
fn1 = () => 66

let x = fn1()

console.log(x)

<!-- 此时 不能执行下面的代码,因为void 不能参与任何逻辑判断及运算 -->
if (x) {
    
}
属性装饰符

1)、public

class Person {
    public name: string
    public age: number
    constructor(name: string, age: number) {
        this.name = name
        this.age = age
    }

    public sayHello() {
        console.log(`你好,我是${this.name}`)
    }
}

let p = new Person('jack', 12)

console.log(p.name)
console.log(p.age)
p.sayHello()
class Person {
    constructor(
        public name: string,
        public age: number
    ) {}

    sayHello() {
        console.log(`你好,我是${this.name}`)
    }
}

class Student extends Person {
    constructor(
        public name: string,
        public age: number,
        public className: string
    ) {
        super(name, age)
    }
}

2)、protected

class Person {
    constructor(
        protected name: string,
        protected age: number
    ) {}

    protected sayHello() {
        console.log(`你好,我是${this.name}`)
    }

    forceSayHello() {
        this.sayHello()
    }
}

let p = new Person('jack', 12)

<!-- 不可调用 -->
// p.name
// p.age
// p.sayHello()

<!-- 可正常调用 -->
p.forceSayHello()

3)、private

class Person {
    constructor(
        private name: string,
        private age: number
    ) {}

    private sayHello() {
        console.log(`你好,我是${this.name}`)
    }

    forceSayHello() {
        this.sayHello()
    }
}

<!-- 此时 类 Student 会报错 -->
<!-- 类“Student”错误扩展基类“Person”。
类型具有私有属性“name”的单独声明。 -->

class Student extends Person {
    constructor(
        private name: string,
        private age: number,
        private className: string
    ) {
        super(name, age)
    }
}

4)、readonly

class Person {
    constructor(
        readonly name: string,
        public age: number
    ) {}

    sayHello() {
        console.log(`你好,我是${this.name}`)
    }

    forceSayHello() {
        this.sayHello()
    }
}

class Student extends Person {
    constructor(
        readonly name: string,
        public age: number,
        public className: string
    ) {
        super(name, age)
    }
}

let p = new Person('jack', 12)

<!-- 不可修改 -->
// p.name = 'tom'
<!-- 其他操作都可以 -->
p.age = 20
p.name
p.age
p.sayHello()
p.forceSayHello()
abstract 抽象类


abstract class Person {
    constructor(
        public name: string,
        public age: number
    ) {}

    abstract sayHello(): void

    forceSayHello() {
        this.sayHello()
    }
}

class Student extends Person {
    constructor(
        public name: string,
        public age: number,
        public className: string
    ) {
        super(name, age)
    }

    sayHello(): void {
        console.log(`我是${this.name}, 今年${this.age}岁了`)
    }
}


let student1 = new Student('tom', 12, '一班')

student1.sayHello()
student1.forceSayHello()
interface
interface PersonInterface {
    name: string
    age: number
    inSchool: boolean
    sayName: () => string
}

class Person implements PersonInterface {
    constructor(
        public name: string,
        public age: number,
        public inSchool: boolean
    ) {}

    sayName = () => {
        return this.name
    }
}


let p = new Person('jack', 12, true)

interface Person {
    name: string
    age: number
    inSchool: boolean
    [key: string]: any
}

const person: Person = {
    name: 'jack',
    age: 12,
    inSchool: true,
    hobby: '篮球'
}
interface GetNameInterface {
    (name: string, age: number): string
}

let fn: GetNameInterface = (name, age) => {
    return name
}
interface PersonInterface {
    name: string
    age: number
}

interface Student extends PersonInterface {
    className: string
}

let student1: Student = {
    name: 'jack',
    age: 20,
    className: '一班'
}
interface PersonInterface {
    name: string
    age: number
}

interface Student extends PersonInterface {
    className: string
}

interface Student {
    siteNum: number
}

let student1: Student = {
    name: 'jack',
    age: 20,
    className: '一班',
    siteNum: 1001
}
泛型
<!-- T 可以是任意自定义字符,可定义多个,用逗号隔开 -->
<!-- 参数在调用时在确定类型 -->
function getData<T, U>(data1: T, data2: U) {
    console.log(data1, data2)
}

getData<string, number>('2', 2)
getData<object, boolean>({ a: 2 }, true)
interface PersonInterface<T> {
    name: string
    age: number
    others: T
}

let person: PersonInterface<string> = {
    name: 'jack',
    age: 23,
    others: '篮球'
}
interface PersonInterface<T> {
    name: string
    age: number
    others: T
}

interface HobbyInterface {
    game: string
    color: string
    num: number
}

let person: PersonInterface<HobbyInterface> = {
    name: 'jack',
    age: 23,
    others: {
        game: 'LOL',
        color: 'red',
        num: 66,
    }
}
declare 类型声明文件

把js文件生成对应.d.ts文件,做TS注解 一般用不到

试验性装饰器(实验阶段)
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容