ts之入门学习

本文介绍了TypeScript的基础数据类型、数组与元组、接口、函数、联合类型、类型推论和类型断言等内容,涵盖了类与对象、枚举、泛型、类型别名和声明文件的使用。适合初学者和进阶者学习TypeScript的高级特性。
摘要由CSDN通过智能技术生成

本文是ts入门学习的记录,如有问题欢迎大家指出。

一、数据类型

1、原始类型

  • Number
  • String
  • Boolean
  • BigInt
  • Symbol
  • Null
  • Undefined

其中 null 和 undefined 较为特殊,是其他任意类型的子集,赋值给其他数据类型的变量不会报错。

let name:string = undefined;
let age:number = null;
  • any

若变量定义 any 类型,变量允许访问任意类型的属性和方法。当数据类型确定时,应避免使用(可以任意调用方法和属性,使其丧失作用)。

2、引用类型

  • Object
  • Array
  • Tuple
  • Function
  • 其他

二、Array 和 Tuple

// 定义数组,定义数组后可以使用数组的方法和属性
// 不允许往数组中添加其他类型的数据,arr.push['123'] 报错
let arr:number[] = [1, 2, 3];

// 定义元组,元组是特殊的数组,允许使用数组的属性和方法
let tup: [number, string] = [10, 'hello'];
// 如上定义,允许往元组中添加 number 或者 string 类型的值,若其他类型报错
tup.push(10);

虽然类数组具备数组一部分的属性,但是数组和类数组的类型是不同的,如果在方法中将类数组赋值给数组,会报错。

元组一定程度上限定数据类型的数组,其本身还是数组,可以使用数组方法。

三、interface接口

interface 用来对对象的形状进行描述,对函数进行描述。

命名一般会首字母大写。

interface Animal {
    name: string;
    age: number
}

// 其形状必须完全和 Animal 一致
let dog:Animal = {
    name: '小白',
    age: 1
}

如果希望对象中一些字段可以不被匹配,可以使用可选属性(?)。

如果希望对象中一些字段不被修改,可以使用可读属性(readonly)。和 const 类似,只是用于属性。

interface Animal {
    readonly id: number;
    name: string;
    age?: number
}

// age 可以不被定义
let dog:Animal = {
    id: 1,
    name: '小白'
}
// id 不可以被修改,dog.id = 2 报错

三、函数

函数需要约定输入和输出。

声明类型(=>是ts中声明类型的方法,凡是在:后面都是声明类型和实际的逻辑没有什么关系)。

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


// 以函数表达式的方式定义函数
// 注意:冒号之后的=>不是es6中的箭头函数,而是ts中定义函数类型的标志
const add1: (x: number, y:number) => number = add


// 使用 interface 描述函数的形状
interface Sum {
    (x:number, y:number): number
}
const add2:Sum = add

如果一个参数可以不被匹配,可使用可选参数。注意:可选参数后不可有确定的参数

function  add (x:number, y:number, z?:number):number {
    return z ? x+y+z : x + y;
}

四、联合类型

在使用联合类型,不能确定变量到底是哪种类型时,该数据只能访问联合类型共有的属性和方法。

let item:number|string;
item = 3;
item = '3';
console.log(item.value);

五、类型推论

类型推论是指当我们没有定义变量的类型,给变量赋值时,ts 会推断该变量的类型,给该变量一个确切的类型。

let name = 'believe'
// ts 会自动将 name 的数据类型设置为 string,再给 name 赋值其他类型的值是会报错

六、类型断言

可以使用 as 关键字告诉 ts,这个变量确切的类型,之后可以访问这个数据类型下的属性和方法

注意:这里并没有改变变量的数据类型。

function getLength(item: number|string):number {
    let str = item as string
    if (str.length) {
        return str.length;
    } else {
        let num = item as number;
        return num.toString().length;
    }
}

类型守护: 通过typeof等判断数据类型,并对其进行相应处理

七、calss类

访问修饰符:

类(定义了一切事物的抽象特点)

对象(类的实例)

面向对象特性:封装、继承、多态

readonly 只能读不能写

  • public:共有的,都能访问
  • private:私有的,不能在类的外部访问
  • protected:受保护的,其和私有的区别在于 protected 修饰的属性或方法可以在子类中访问
class Animal {
    readonly name:string
    constructor(name) {
        this.name = name
    }
    run() {
        return `${this.name} is running`
    }
}
class Dog extends Animal{
    bark() {
        return `${this.name} is barking`
    }
}
class Cat extends Animal{
    static categories=['animal']
    constructor(name) {
        super(name);
        console.log(this.name)
    }
    run() {
        return `Meow, ${super.run()}`
    }
}
const snake=new Animal('lily')
// snake.name = '123' 报错
console.log(snake.run())

const dog = new Dog('xiaogou')
console.log(dog.bark())
console.log(dog.run())

const cat = new Cat('maomao')
console.log(cat.run())
console.log(Cat.categories)

类可以使用 implements 来实现接口,实现逻辑的提取和验证。接口之间可以有继承的关系,和类的继承相似。

interface Radio {
    switchRadio (trigger: boolean): void;
}
interface Battery {
    checkBattery(): void
}
interface RadioWithBattery extends Radio{
    checkBattery(): void
}
class Car implements Radio{
    switchRadio (trigger: boolean) {

    }
}

// 以下两种效果相同相同
/*class Phone implements Radio,Battery {
    switchRadio (trigger: boolean) {

    }
    checkBattery() {}
}*/
class Phone implements RadioWithBattery{
    switchRadio (trigger: boolean) {

    }
    checkBattery() {}
}

八、枚举

枚举,在一定范围内的一系列常量

枚举默认会被从0开始赋值,手动赋值会接着上一个递增

// 数字枚举
enum Direction {
    Up=10,
    Down,
    Left,
    Right
}
// 可以看成数组,反向的取值
console.log(Direction.Up)
console.log(Direction[0])

// 字符串枚举
enum Direction {
    Up='Up',
    Down='Down',
    Left='Left',
    Right='Right'
}

枚举值分为常量值和计算值,只有常量值可以计算常量枚举

九、泛型

定义函数和类时,不预先指定类型,而在使用时才指定类型

名称叫什么都可以,相当于占位符

function echo<T>(arg:T):T {
    return arg
}
const result = echo(true)


function swap<T, U>(tuple: [T,U]): [U, T] {
    return [tuple[1], tuple[0]]
}
const result1 = swap(['str', 123])

约束泛型

在使用泛型时,由于不能提前知道是哪种类型,不能随意的操作变量的属性和方法

// 这种解决方案不完美,规定其为数组,不能传入其他类型
function echoArr<T>(arg:T[]):T[] {
    console.log(arg.length)
    return arg
}
const result = echoArr([1,2,3])

使用 extends 使泛型满足特定的约束条件,而不时想传入什么就传入什么

interface Length {
    length:number
}
function echoLength<T extends Length>(arg:T):T {
    console.log(arg.length)
    return arg
}
const str = echoLength('123')
const obj = echoLength({length: 10})
const arr = echoLength([1,2,3])

泛型在其方面的应用

// 创建特定数据类型的队列
class Queue<T> {
    private data = [];
    push(item: T) {
        return this.data.push(item)
    }
    pop(): T {
        return this.data.shift()
    }
}
const queue = new Queue<number>()
queue.push(1)
queue.push(2)
console.log(queue.pop().toFixed())
console.log(queue.pop().toFixed())

interface 接口

interface KeyPair<T, U> {
    key: T,
    value: U
}
let kp1: KeyPair<number, string> = {key:1, value: 'str'}
let arr: Array<number> = [1, 2]

泛型的作用

  • 创建特定类型的容器
  • 灵活的约束参数的类型
  • 在函数使用时,函数的类型推断不会流入函数体内,使用表达式不能明确的绑定,所以使用泛型来打破这一鸿沟

十、类型别名、交叉类型

类型别名

使用 type 来定义类型别名

type 定义了类型的别名,用于交叉组合类型的情况;interface 是一种独特的类型

let sum: (x:number,y:number) => number
const result = sum(1,2)
type PlusType =  (x:number,y:number) => number
let sum2: PlusType
const result1 = sum2(1,2)

字面量

特殊的类型,确定了变量只能等与特定的值

const str: 'name' = 'name'
type Directions = 'Up'|'Down'|'Left'|'Right'
let toWhere: Directions = 'Up'

交叉类型

interface Name {
    name: string
}
// person具有age和name属性
type Person = Name & {age: Number}
let person: Person = {name: '123', age:1}

十一、声明文件

声明文件,使用 declare 关键字,来告诉ts这个类已经被定义,通常放入一个单独的文件通常以 .d.ts 结尾。

declare 并没有定义类的实现,仅仅定义了类型,来应对编译的检查。

declare var JQuery:(selector:string)=> any
JQuery('#foo')

十二、内置类型

const a: Array<number> = [1,2,3]
const date = new Date()
date.getTime()
const reg = /abc/
reg.test('abc')
Math.pow(1,2)


// dom 和 bom
let body = document.body
let allLis = document.querySelectorAll('Li')
allLis.keys()

// 根据类型推断,回调函数中的参数自动获取数据类型
document.addEventListener('click', (e)=> {})

Utility Types

Partial 把所有的数据变为可选

Omit 可以忽略某个传入类的属性

interface Person {
    name: string,
    age: number
}
let viking: Person = {name: 'viking', age: 1}
type Person1 = Partial<Person>
let viking2 = {}
type Person2 = Omit<Person, 'name'>
let viking3 = {age: 1}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值