1、ts 基本类型约束

595 阅读5分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第2天,点击查看活动详情

温馨提示: TS 是一个可选的静态的类型系统, 要是你用的不开心, 不用就行了 哈哈

如何进行类型约束

通过类型约束: 变量、函数的参数、函数的返回值, 这几种常用的值, 当有了类型约束才可以进行类型检查。

使用: 仅需要在 变量、函数的参数、函数的返回值位置上加上 :类型

基本类型

  • number:数字
  • string:字符串
  • boolean:布尔
  • null 和 undefined 是所有其它类型的子类型, 它们可以赋值给其它类型

举例:

    let a:number = null; //success
    let b:string = undefined; //success

这在 ts 中是合法的, 所以这里是存在隐患的, 为了避免这种情况可以在配置文件中加入 compilerOptions.strictNullChecks:true 表示更加严格的空类型检查, 开启该置上面的写法在 ts 中是不合法的。

类型举例

变量

let name: string : 给变量定义为 字符串 类型, 后续的赋值只能给 name 赋值为 字符创 类型否则报错。

image.png

可以写为: let name:string = '托尼'

函数参数, 函数返回值

    function sum(a: number, b: number): number {
        return a + b
    }

函数参数的类型约束就直接写在 参数后面,返回值写在 大括号前, 上面的代码表示 参数 a 必须传递 number 类型,b 同上, 函数返回的结果必须是 number 类型, 在使用该函数就必须遵守这个 参数的规则不然就报错

image.png

并且使用该函数必须传递两个参数,不然也会报错

image.png

其它常用类型

联合类型

let name: string | undefined;

表示 name 可以是 string 类型,也可以是 undefined 类型

    let name: string | undefined;
    if(typeof name === 'string'){
        //代码执行到这里 ts 就认为 name 一定是 string 类型
    }

这个叫做 ts 的类型保护

void 类型

通常用于约束函数的返回值, 表示该函数没有任何返回值。

never 类型

通常用于约束函数的返回值, 表示该函数永远不可能结束

    //该函数永远 不可能结束
    function s ():never {
        where(true){
        
        }
    }
    
    //该函数永远 不可能结束
    function err(): never {
    throw new Error('错误')
}

字面量类型

let str:'A'; 表示 str 只能赋值为 'A'

let obj:{
    name: string
    age: number
}

表示 obj 是能是带有 name 和 age 的属性名的对象

元祖类型(Tuple)

一个固定长度的数组, 并且数组中每一项的类型确定。

let tu: [string, number]; //表示 tu 只能是两项 第一项必须是 string 第二项必须是 number

any类型

any 类型可以绕过类型检查, 这就和平时写 js 没有差异。

any 类型可以赋值给其他类型

let str: any = '123'
let num: number = str

在 ts 中是合法的, 但是这就导致了隐患, 所以不推荐这样使用。

引用类型

数组

这里我想创建一个 number 的数组: 改数组的每一项为 number 类型

let nums: Array<number>;

let nums: number[]; 这是上面写法的 语法糖

都表示为创建一个 number 类型的数组

对象

let obj: object obj 可以有任何的属性, 所以用这种方式约束对象不常用, 在后面的文章中会介绍有可以约束 对象有哪些属性的手段

ts 在很多场景中可以完成类型推导

ts 能只能的推导运算结果是什么类型

    function sum(a: number, b: number) {
            return a + b
    }
    
    let a = sum(1, 2)

不给这个 sum 函数指定返回类型, ts 能够只能的判断出 sum 函数会返回 number 类型,所以 a 变量也是一个 number 类型

vscode 编辑器中, 我怎么知道有没有推导成功看下图:

image.png

有这个存在的时候 就说明 ts 就无法推导出该类型到底是什么,这里就需要手动约束了。如果没有推导出来就默认为

类型别名

类型别名 像是一种 提取公共代码

let user:{
    name: string
    age: number
    gender: '女' | '男'
}

// 假如有这样一个函数, 会返回 上面对象类型的数组, 根据上面的知识可以这样写
function getUsers():{
    name: string
    age: number
    gender: '女' | '男'
}[]{

}

上面的写法 很明显不够优雅 也会存在代码冗余

所以这里可以使用类型别名, 把共同的代码提取出来去一个名字。

type userType = {
    name: string
    age: number
    gender: '女' | '男'
}
let user:userType

function getUsers():userType[]{}

约束函数

//第一种
type Condition = (item: number, index: number): boolean
//第二种
type Condition = {
    (item: number, index: number): boolean
}

类似继承的写法

type a = {
    a:number
}
type b = {
    b:string
}
type c = {
    c:boolean
} & a & b

类型别名可以定义为任何类型, 要学会举一反三。

函数的相关约束

函数重载

在函数实现之前, 对函数调用的多种情况进行声明。

举例

现在有一个函数,该函数有两个参数, 当这两个参数全为 number 类型, 或者全为 string 类型 时进行不同的操作。

type Arg = number | string
function combin(a: Arg, b: Arg): Arg{
    if(typeof a === 'number' && typeof b === 'number'){
        return a * b
    }else if (typeof a === 'string' && typeof b === 'string') {
        return a + b
    }else{
        throw new Error('a 和 b 必须是相同类型。')
    }
}

这里假如有变量使用了这个函数

    const n = combin(1,2)

此时 n 的类型 ts 判断为不是 number | string 但是我知道这个 n 一定是 number, 所以上面的函数缺少了 函数重载

加上 函数重载

type Arg = number | string
//============================================
function combin(a: number, n: number): number
function combin(a: string, n: string): string
//============================================
function combin(a: Arg, b: Arg): Arg {
    if (typeof a === 'number' && typeof b === 'number') {
        return a * b
    } else if (typeof a === 'string' && typeof b === 'string') {
        return a + b
    } else {
        throw new Error('a 和 b 必须是相同类型。')
    }
}

const n = combin(1, 2)

这就很明确的告诉 ts 传递什么参数, 返回什么类型。 此时 n 就一定是 number。

可选参数

可以在某些参数后加上 ?, 表示该参数可以不用传递。

注意: 可选参数只能出现在参数末尾。

function ao(a: number, b?: number) {
    return a + (b || 0);
}

总结

ts 是一门可选的类型检查系统, 它不会存在我们的编译结果中, 它只在开发的过程中提升我们代码的健壮性, 从而减少代码隐藏的风险, 至于你使不使用 ts 全看你心情.