TypeScript —— TS中的数据类型

556 阅读7分钟

基本类型

布尔类型

// 布尔类型
// 只有true和false
let bool: boolean = true

// 这里的类型首字母大小写皆可
let bool: Boolean = false

// 也可以先定义后赋值
let bool: boolean
bool = true

// 不可以将数字字面量类型赋值给布尔类型的变量
bool = 123 // => error

数值类型

// 数值类型
// js和ts一样,所有的数值类型在存储的时候,全部采用的是浮点类型
let num: number = 123

// 数值类型支持
//  1. 十进制
num = 123

//  2. 二进制 (字母b大小写皆可)
num = 0b1111011
num = 0B1111011

//  3. 八进制 (字母o大小写皆可)
num = 0o173
num = 0O173

// 4. 十六进制(字母x大小写皆可)
num = 0x7b
num = 0X7b
num = 0X7B


// PS:在进制中,所有的字母大小写都不会进行区分

字符串类型

// 字符串类型
let str = 'Klaus'

// 可以使用模板字符串字符串
str = `My Name is ${str}`

数组类型

// 数组类型

// 定义方式1
let arr: number[] = [1, 2]

// 最后一个元素不写也是可以的
arr = [1, 2,]


// 定义方式2
let arr2: Array<number>
arr2 = [1, 2, 3]

// 在js中数组可能存的类型不一定一定要同一种类型
// 此时就需要使用联合类型

// 注意这里的类型括号是不可以省略的
// let arr3: number | string[] => arr3 可以存储的类型为number 或 字符串数组
let arr3: (number | string)[] = [1, 'Klaus']
let arr4: Array<number | string> = [2, 'Steven']

元组类型

// 元组类型
// ts中元组类型 === 数组的扩展
// 元组 === 类型和长度 固定的数组

let tuple: [number, string, boolean]
tuple = [1, 'Klaus', true]

// 1. 元素长度不够
// tuple = [1] // => error

// 2. 元素的对应元素类型不匹配
// tuple = [1, 2, true] // => error

// 3. 存在越界元素
tuple = [1, 'Klaus', true, 3] // => error

枚举类型

// 枚举类型
// 枚举类型 本质上 是一个特殊的对象

// 1. 一般情况下,枚举类型的首字母需要大写
// 2. 枚举类型中定义的值可以变相理解为常量,所以其中的值也应该按照常量的定义,全部使用大写的方式
// 3. 最后的逗号加不加无所谓(即USER 和 USER, )都是一样的,但是推荐不要加上
enum Roles { 
    ROOT,
    ADMIN,
    USER
}

// =>
/**
 * 编译后
 * var Roles;
 *  // 编译为了一个IIFE 
 *   (function (Roles) {
 *       Roles[Roles["ROOT"] = 0] = "ROOT";
 *       Roles[Roles["ADMIN"] = 1] = "ADMIN";
 *       Roles[Roles["USER"] = 2] = "USER";
 *   })(Roles || (Roles = {}));
 */
// 枚举类型的默认值是从0开始的递增递增为1的索引
enum Roles { 
    ROOT,
    ADMIN,
    USER,
    ANONYMOUS
}

/**
 * ROOT === 0
 * ADMIN === 1
 * USER === 2
 * ANONYMOUS === 3
 */
// 可以在任意位置 设置默认值
// 设置完默认值开始,其后的值会自动递增1
enum Roles { 
    ROOT = 1,
    ADMIN,
    USER,
    ANONYMOUS
}

/**
 * ROOT === 1
 * ADMIN === 2
 * USER === 3
 * ANONYMOUS === 4
 */

// -----------------------------------------------

// 可以在任意位置 设置默认值
// 设置完默认值开始,其后的值会自动递增1
enum Roles { 
    ROOT,
    ADMIN,
    USER = 4,
    ANONYMOUS
}

/**
 * ROOT === 0
 * ADMIN === 1
 * USER === 4
 * ANONYMOUS === 5
 */

// ---------------------------------------------------

// 可以在任意位置 设置默认值
// 设置完默认值开始,其后的值会自动递增1
enum Roles { 
    ROOT,
    ADMIN,
    USER = 1,
    ANONYMOUS
}

/**
 * ROOT === 0
 * ADMIN === 1
 * USER === 1
 * ANONYMOUS === 2
 */

// 后边赋的值会将之前所赋的值给覆盖
console.log(Roles.ADMIN) // => 1
console.log(Roles.USER) // => 1
console.log(Roles[1]) // => USER

// ---------------------------------------------------

// 可以全部给每一个值皆自定义值
enum Roles { 
    ROOT = 2,
    ADMIN = 4,
    USER = 6,
    ANONYMOUS = 8
}

// ------------------------------------------------------

// 如果赋的值是字符串字符串
// 那么其不会自增1 
// 所以其中的每一个值都必须进行手动赋值
enum Roles { 
    ROOT = 'root',
    ADMIN = 'admin',
    USER = 'user' ,
    ANONYMOUS = 'anonymous'
}

any

// any类型
// 任何类型
// 适合于在编写时候不知道是什么类型的时候使用
let v: any
v = 1
v = 'Klaus'
v = [1, 2]

// 过多的使用any类型 会导致 TS的类型检测失去作用
// 所以 尽量不要去使用any类型

void

// void 
// 和 any正好相反
// void 表示的是没有类型
// 一般用于一个函数,没有返回值的时候
const consoleText = text => console.log(text)

// 1:函数返回值如果没有写,其会自动去推测其返回值类型,所以可以省略

// 2. 在严格模式下,参数必须书写类型,非严格模式下,没有类型会隐式转换为anyany

// 3. undefined 和 null 是 void 的子类型

// 所以在上述函数中,没有return,所以默认返回的是undefined,
// undefined是void的子类型,可以赋值给void

// 非严格模式
let v: void = undefined //=> success
    v: void = null // => success

// 注意: 如果开启了严格模式,null是不可以作为void的子类型

// 严格模式
let v: void = undefined //=> success
	v: void = null // => error

null 和 undefined

// null 和 undefined
// 在js中 null和undefined是基本数据类型
// 在ts中 null和undefined即是值,也是类型


// undefined 只有一个值 叫做undefined
let u: undefined = undefined
// u = 123 // => error

// null也只有一个值 叫做 nullnull
let n: null = null
// n = 123 // => error

// null 和 undefined 是其它类型的子类型
// 也就是说 null 和 undefined 赋予其它任意类型的值
let num: number = 123
num = null // => success
num = undefined // => success

// 注意:如果开启了严格模式
// 或者开启了严格模式中的strictNullChecks
// 也就意味了对null和undefined进行严格赋值检测
// 即 null 只能赋值给 null类型的值
// undefined 只能赋值给 undefinedned类型的值

// 开启严格模式 或 strictNullullChecks后
let num1: number = 123
num1 = null // => error
num1 = undefined // => error

never

// never
// 表示的是那些永远不存在的那些值的类型

// never 类型适用于 以下2个场景
// 1. 该函数会抛出一个异常或者错误
// 即 该函数无法正常执行完成
const errorMsg = (message: string): never => { 
    throw new Error(message)
}


// 2. 死循环函数,这类函数也是无法正常执行完成
const InfiniteFunc = (): never => { 
    while (true) { 
        console.log('InfiniteFunc')
    }
}
// never 类型的值是其它任意类型的子类型
// 没有任何一种类型是never类型的子类型 

// 定义一个never类型
let neverVar: never = (function () { 
    while (true) { }
})()

neverVar = 123 // => error
neverVar = null // => error
neverVar = undefined // => error

let num: number = 123
num = neverVar // => success

object

// object
// 对象 => 对象是引用数据类型
// 存储的是该对象在内存中的地址的引用

let o: object = {
    name: 'Klaus'
}

function printNum(o: object): void { 
    console.log(o)
}


printNum(o) // => success
printNum(123) // => error

类型断言

// 类型断言
// 类似于强制类型声明
// 也就是 强制类型转换

/**
 *  这段代码中 
 *  target.length || target.length === 0 中的length是标红
 *  原因是: 
 *      target 可能是 number,也可能是string
 *      如果是 number 没有 length 属性 
 *      所以报错
 *  
 *   此时我们代码中 target.length || target.length === 0
 *   如果被执行的时候,typeof target 一定是 stringstring
 *   所以此处需要使用类型断言
 *   告诉tsc,这里是字符串,不要对其进行别的类型校验,
 *   按照string类型来进行编译
 */
const getLength = (target: string | number): number => { 
    // 如果是字符串,返回字符串的长度
    if (target.length || target.length === 0) { // => 此处的2个length是会标红的
        return target.length // => 此处的length是会标红的
    } else { 
        // 如果不是number, 转换为字符串进行返回
        return target.toString().length
    }
}
// 添加类型断言的方式有2种
// 1. 尖括号 (类似于泛型)
// 2. as 关键字

// 注意: 如果使用jsx
// 那么类型断言只支持 as的方式
// 不支持尖括号的方式
// 因为尖括号在jsx中可能会被误识别为自定义组件
// 所以不被支持

const getLength = (target: string | number): number => { 
    // 如果是字符串,返回字符串的长度
    if ((<string>target).length || (target as string).length === 0) {
        // 注意: 断言需要在外边加上括号
        // 表示断言的数据类型和变量是一个整体
        // 否则tsc只会识别类型,无法识别所设置的断言
        return (<string>target).length
    } else { 
        // 如果不是number, 转换为字符串进行返回
        return target.toString().length
    }
}