TypeScript 学习总结 基础数据类型(一)

写在前面javascript

由于typescript文档我的感受写得很差(概念过于杂乱,示例代码有错误~)。因此总结一下TS的知识java

这是我的学习笔记总结,并无官方文档严谨。更多的是我的的大白话react

代码部分 推荐各位复制到支持TS的代码编辑器里 看看什么效果。体验一下 TS在编译阶段的严谨~~typescript

想学习TypeScript的朋友能够快速扫两眼,入个门~ json


基础数据类型:


首先typescript的基础数据类型:redux

  • 布尔类型(boolean)数组

  • 数字类型(number)dom

  • 字符串类型(string)编辑器

  • 数组类型(array)函数

  • 元组类型(tuple)

  • 枚举类型(enum)

  • 任意值类型(any)

  • null 和 undefined

  • void类型

  • never类型

  • object 类型

  • 类型断言

  • Symbol 类型


布尔类型(boolean)


布尔类型是最简单的数据类型,只能赋值为truefalse两种值,不能赋予其余的值

类型注解: 其实就是指定各类类型, boolean, string之类的。其余语言也叫类型注解 因此统一一下

基础语法:
变量:类型注解 = 对应类型注解的值  
let bol: boolean = true  
let bol2: boolean  
bol2 =  false
bol = blo2  // 能够 bol是boolean类型 因此能够赋值false

bol = ' 1'  //Type '"1"' is not assignable to type'boolean'. 字符串不能赋值给boolean类型
复制代码

除了规定了变量类型以外,其余语法与javascript同样。

数字类型(number)


和JavaScript同样,TypeScript数字都是浮点型( 1 在JS眼里是 1.0),也支持二进制、八进制、十进制和十六进制

let num1: number = 123       //十进制 
num1 = 0b01111011            //二进制 0b开头 ES6引入
num1 = 0o173                 //八进制 0o开头 ES6引入
num1= 0x7b                   //十六进制 0x开头

如下是特殊的number类型:
num1 = Infinity              //无穷大
num1 = -Infinity             //负无穷大
num1 = NaN                   //Not a Number
复制代码

字符串类型(string)


"" ,''和ES6模板字符串\` `.包裹起来的值,都是字符串类型

let str: string = '哈哈哈'
let str2: string = `笑声${str}`
复制代码

数组类型(array)


TypeScript 提供了两种定义数组类型的方法。一种是在类型后加上 []表示这是一个数组。 推荐优先使用这种写法

语法:
let 变量:类型注解[]

let arr1: number[]  //number类型数组,只能存number类型
arr1 = [5,1,3]   // true
arr1 = ['1']     // false 只能够赋值number类型
复制代码

另外一种方法是使用泛型表示:Array < T> ,其中 T 为数组中元素的类型。

语法:
let 变量:Array<T>  //这里的 <T> 代指泛型。 能够简单的理解为就是一个占位符,'暂时'没有实际的类型。类型根据使用时传入的值而定。泛型后续会详解

let arr2 : Array<string> //string 数组
arr = ['1','a','haha']

let arr3 : Array<boolean> = [true,false,true] //boolean数组
复制代码

元组类型(tuple)


元组类型就是一个特殊的数组。

表示已知数量已知元素类型的数组, 里面的每一项能够是不一样的类型

语法:
let 变量:[类型1,类型2....]

let arr : [string, number, boolean,number[]] 
//1.数量固定,只能传四个元素,不可少传也不可多传
//2.各索引位的元素类型固定,不可改变。

arr = ['1', 2, true, numArr] // true 必须按照 固定数量和类型顺序赋值

如下是错误写法:
arr = [1, 2, true, numArr]      //error 第一个位置接收string类型,却传入number。类型不匹配
arr = [1, '2', true, numArr]    //error 同上 ,前两个位置类型不匹配
arr = ['2']                     // error arr必须接受4个参数,这里只传入一个
arr = [1, '2', true, numArr, 2] // error 传入过多的参数也不行,最后一个为越界元素。如今数组的length为4,不能传入第五个值

复制代码

枚举类型(enum)


枚举用来表示一些逻辑上有关联的数据,而且这些数据不能被修改的。让这些数据更有语义化。

枚举类型里面的值都是只读的,只能读取不能修改

语法:
enum 标识符 {
    值,
    值
    ...
}
------------------------------------------------------
//应用场景:假设根据后台传入数据,让咱们来判断用户权限操做
//传递的数据里有id。id存储的number类型的数据,咱们依次来判断
roles = {
id:xxx,
...
}

//无语义化写法:
switch(roles.id) {
    case 0:
        //普通用户
        break;
    case 1:
        //员工
        break;
    case 2:
        //管理员
        break;
}
//缺点须要写文档注释,代表0 , 1...是什么意思

//使用枚举,定义一组用户数据:
enum Roles {
    USER,   //0
    STAFF,  //1
    ADMIN   //2
}
// 每一个枚举类型的值,都有对应的索引值,默认从0开始依次递增
// 取值操做相似于JS对象
Roles.USER // 0 经过属性取索引
Roles[0] // USER 经过索引取属性值 下面会解释是如何实现的

// 使用Roles来做为判断条件
switch(roles.id) {
    case Roles.USER:  // 0
        //普通用户
        break;
    case Roles.STAFF: // 1
        //员工
        break;
    case Roles.ADMIN: // 2
        //管理员
        break;
}
// 更有语义化,代码直观易读
--------------------------------------------------------------------------------------------------------------------
// 将枚举类型,转化为JS。看是如何实现的
enum Roles {
    USER,   //0
    STAFF,  //1
    ADMIN   //2
}

//JS代码
var Roles;
(function (Roles) {
    Roles[Roles["USER"] = 0] = "USER";
    Roles[Roles["STAFF"] = 1] = "STAFF";
    Roles[Roles["ADMIN"] = 2] = "ADMIN"; 
})(Roles || (Roles = {}));

解析:
首先Roles是个对象,而后当即执行函数会对这个对象进行赋值

Roles[Roles["USER"] = 0] = "USER";
能够分解为:
首先给Roles设置一个 USER 的属性,赋值为0
Roles["USER"] = 0  //这步操做是有返回值的 返回值就是 = 右边的值 此处为0, ~~能够测试自行建立一个对象,再赋值看返回的结果
而后将上一步的返回值做为属性名,再次赋值
Roles[0] = "USER"
因此能够经过索引或属性名取相互的值,很是巧妙
Roles[0]  // USER
Roles["USER"] // 0
--------------------------------------------------------------------------------------------------------------------
// 在定义枚举时,能够自定义索引值
enum English {
    A = 1,      // 1
    B,          // 2
    D = 4,      // 4
    E           // 5
}

let a = English.A   // 1
let c = English.B   // 2
let d = English.D   // 4
let e = English.E   // 5
let eng = English[5] // E

//自定义索引值只会影响,后续值的索引值(自动根据前一个增长)
enum english {
    a,         // 默认值 0
    b = 2,     // 2 影响排在其后的元素
    c,         // 3 
    d,         // 4
    e          // 5
}

english.a = 1 //error 枚举类型里的值是只读类型,只容许读取
english[a] //error 枚举类型里面的值,是字符串。这样取值是错误的,会去找同名变量,进行操做。
english['a'] //ok
------------------------------------------------------------------------------------------------------------------
枚举类型,后续还有不少用法。好比说使用redux时,用来存储Action的type
复制代码

any (任意类型)


any表示任意类型,任何值均可以传入any

any类型 上是类型系统的逃生舱口(走后门)。TS不会对any类型进行检查

万物皆any~

let value: any;

value = true;             // OK
value = 42;               // OK
value = "Hello World";    // OK
value = [];               // OK
value = {};               // OK
value = Math.random;      // OK
value = null;             // OK
value = undefined;        // OK
value = new TypeError();  // OK
value = Symbol("type");   // OK
// 如今变量能够任意赋值,和原生JS平时操做没有任何限制同样
--------------------------------------------------------
let anyArr: any[] = [1,24,5,'hhh',['qqq'],true] 

// 虽然方便,但尽可能少使用。否者就失去了使用TS的意义,没有类型检查的保障,代码容易出问题。
// 通常在将JS代码重构为TS时,使用的较多
复制代码

void 类型


void表示没有任何类型, 经常使用在函数没有返回值的状况下指定,表示一个函数没有返回值

// 例子:
let func = (name:string):void => {
    console.log(`hello, $(name)`)
    // 这个函数没有指定任何返回值
    // 但在JS里 函数都会默认返回undefined。void会默认兼容undefined类型
}
func(456) // error 参数必须是是string类型。这就体现了TS的好处了,编译阶段就会提醒错误
func('Bob') // true

let num:void 
num = undefined //true 
num = null    //error
num = 1      // error 

let V: any; 
num = V // true 再次强调 any类型能够兼容其余全部类型(除never外)~


void 大部分场景用在函数的返回值类型上,关于函数的知识后续会讲解
复制代码

null 和 undefined 类型


1.在TS中null undefined既是类型,也能够做为普通的值使用。参考上面函数默认返回值undefined

2.在TS非严格模式下nullundefined同时也是其余类型的子类型(其余类型能够兼容这两个值), 严格模式下会报错

tsconfig.json(ts配置文件):strict: false (非严格模式下)(其中一个选项,默认是true 严格模式):

let isNull: null  // null类型只能接收 null类型 和 undefined类
let isUndefined: undefined // undefined类型只能接收 undefined类型 和 null类型
isNull = null //true
isNull = 1 //error
isNull = undefined //true
isUndefined = null //true
isUndefined = undefined //true
isUndefined = '2' //error

let str: string
str = null //true
str = undefined //true

--------------------------------------------------------------
tsconfig.json:strict: true (严格模式下):

let isNull: null  // null类型只能接收null值
let isUndefined: undefined // undefined类型只能接收undefined值
isNull = null //true
isNull = 1 //error
isNull = undefined //error
isUndefined = null //error
isUndefined = undefined //true
isUndefined = '2' //error

let str: string
str = null //error 严格模式下报错,不能做为子类型
str = undefined //error

复制代码

never 类型


never 类型比较抽象,表示永远不存在的值

非严格模式下never类型是任何类型的子类型,也能够赋值给任何类型.

//常见的两种状况 抛出错误和死循环 
const errorFunc = (message: string): never => {
    throw new Error(message)
}

const infiniteFunc = ():never => {
    while(true){}
}
------------------------------------------------------
tsconfig.json中:strict: false (非严格模式下):

let str: string
let isNever: never
str = isNever // true
isNever = str //error
复制代码

object 类型


object 类型,就是用来表示引用类型的。与JS对象无差异

let obj = {
    name: 'Bob'
}
obj.sex = 'man'

const getObject = (obj: object):void => { 
    console.log(obj)
}

getObject('hahah') // error
getObject(obj)    // true
复制代码

类型断言


混淆是非,把某个值,强制指定为咱们须要的类型,TS就会按照咱们指定的类型进行检查

能够理解为 相似于强制类型转换。只是相似┗|`O′|┛ 嗷~~

语法: 两种写法。
1. <类型>值 
2.as 类型   //react技术栈 编写JSX时,必须使用这个。上面的和JSX语法有歧义

// 需求 有个函数接收一个string或者number类型的值。
// 若是是string 咱们直接返回字符串的长度
// 若是是number 我门把number转化为字符串,在返回长度

const getLength = (target: string | number): number => {
               // target的类型能够是string或number. 这是联合类型的语法。后续会讲解
    if(target.length) {  //提示错误
        return target.length //提示错误
    } else {
        return target.toString().length
    }
}
getLength(1) // 正常
getLength('hh') //正常
// 上面的代码,逻辑没有问题。
// 但在TS写代码过程当中就会提示错误,TS会认为这个代码是有问题的。首先编译阶段参数类型还没肯定,会把number 和 string 都做为参数类型进行检测
// string有length属性能够经过。number没有length属性,因此TS在编译阶段就会提示number没有length属性。
// 代码能正常编译为JS,也能正常运行。由于JS是运行时才会检测代码。但一直提示错误 属实很差看

//使用类型断言解决这个问题。 
const getLength2 = (target: string | number): number => { 
    // 把<string>target,把target指定为了string类型,这样代码就会按照string类型就行检测。
      if((<string>target).length) { return (target as string).length //同上 类型断言第二种写法,加()是由于运算符优先级的问题 } else { return target.toString().length } } getLength2(1) //ok //若是传入number类型,运行阶段仍是会走 toString 那行代码。 //类型断言并非说把target转化为string类型了。仅仅是在编译阶段 让TS跟着你指定的类型进行检测 getLength2('hh') //ok 复制代码

Symbol 类型的讲解推荐去看阮一峰老师的ES6入门教程。TS基本上与ES6没有多大区别 除了TS扩展的类型~,因此人们常说ES6学好了,学TS会很容易
相关文章
相关标签/搜索