typeScript从入门到进阶-基础篇(二)

建议先从 typeScript从入门到进阶-基础篇(一)开始学习

基本类型

ES6的数据类型TS的数据类型
BooleanBoolean
NumberNumber
StringString
ArrayArray
FunctionFunction
ObjectObject
SymbolSymbol
undefindundefind
nullnull
-void
-any
-never
-元组
-枚举
-高级类型
类型注解
  • 作用:相当于强类型语言中的类型声明
  • 语法:(变量/函数):type
// 原始类型
let bool: boolean = true
let num: number = 124
let str: string = 'abc'

// 数组
let arr1 = number[] = [1, 2, 3]
let arr2 = Array<number> = [1, 2, 3]
let arr3 = Array<number | string> =  [1, 2, 3, '4']

// 元组 一种特殊的数组,限定了元素的类型和个数
let tuple: [number, string ] = [0, '1']
// 元组的越界问题:
tuple.push(2)  
console.log(tuple) // [0, '1', 2]
tuple[2]  // 报错不能访问,开发时不建议这样做

// 函数
let add = (x: number, y: number): number => x + y
let add = (x: number, y: number) => x + y // 返回值类型number可以省略

let compute: (x: number,y: number) => number // 函数类型的定义
compute = (a, b) =>  a + b // 函数的实际定义中,形参可以和定义不一样,也可以不用指定具体类型
   
// 对象
let obj: {x: number, y: number} = {x: 1, y: 2}
obj.x = 3

// symbol 具有唯一的值
let s1: symbol = Symbol()
let s2 = Symbol()
console.log(s1 === s2 ) // false

// undefind, null
// 一旦被赋值成undefind 就不能再赋值任何类型了

let un: undifind = undefind
let nu: null = null 

// 在ts官方的文档中,undefind 和 null 是任何类型的子类型,说明可以被赋值成其他类型
// 这里需要做一些设置:
// 在tsconfig.json  设置"strictNullChecks": false,就允许赋值了
// 但是需要注意: 声明需要加上null和undefind才能通过类型检查
let num: number | null | undefind = 124

// void
// 在ts中,void 表示一种没有任何返回值的类型
// 在js中,void 是一种操作符,可以让任何表达式返回undefind 

let noReturn = () => {} // 一个没有任何返回值的函数

void 0 // undefind  为什么会有这种操作?
// 在js中,undefind不是一个保留字,我们甚至可以自定义一个undefind去覆盖全局的undefind;
(function() {
    var undefind = 0
    console.log(undefind)
})()


// any 
在ts中不指定变量的类型,默认就是any类型,不建议使用any
let x
x = 1
x = []
x = '2'

// never
// 表示永远不会有返回值的类型
let error = () => {  // 函数抛出异常
    throw new Error('error')
}
let endLess = () => { // 死循环函数
    while(true){}
}
枚举类型

一组有名字的常量集合

  • 枚举成员的值是只读类型的,一旦定义了不能修改
  • 实现原理:反向映射,枚举被编译成了一个对象,枚举成员的名称被作为了key,枚举成员的值被作为了value,value又作为key,成员的名称又被作为value;
  • 适用情况:将程序中不容易记忆的硬编码,或者在未来可能改变的常量抽取出来,定义成枚举类型,可以提高程序的可读性和可维护性
enum {
    Reporter = 1,
    Developer
}

最终被编译成:
"use strict"
var Role;
(function(Role){
    Role[Role["Reporter"] = 1] = "Reporter"];
    Role[Role["developer"] = 1] = "developer"];
}
)(Role || {Role = {})
// 数字枚举
enum {
    Reporter = 1, // 可以给默认值
    Developer
}

// 字符串枚举(不能进行反向映射)
enum Message {
    Success = "恭喜,恭喜",
    Fail = "再接再厉"
}

// 异构枚举 (容易引起混淆,不建议使用)
enum Answer {
    N,
    Y = 'yse'
}

// 枚举成员
类型:1.const 常量枚举,常量枚举会在编译时计算出结果,然后以常量的形式出现在运行时环境
        包括三种情况: 
        - 没有初始值的情况
        - 对已有枚举成员的引用
        - 常量的表达式
      2.computed number,一定要被赋予初始值;
      需要被计算的枚举成员,非常量的表达式,不会再编一阶段进行计算,而会保留到程序的执行阶段
enum Char {
    // const
    a,  
    b =  Char.a, 
    c = 1 + 3,
    // computed
    d = Math.random(),
    e = '123'.length
}

// 常量枚举:用const声明的枚举,在编译阶段会被移除
    - 当不需要对象,只需要一个对象的值的时候可以用常量枚举
const enum Month = {
    Jan,
    Feb,
    Mar
}
let month = [Month.Jan, Month.Feb, Month.Mar]

// 枚举类型
// - 在某些情况下,枚举和枚举成员都可以作为一种单独的类型存在
enum E { a, b }  // 没有初始值
enum F { a = 0, b = 1 } // 所有初始值都是数字枚举
enum G { a = 'apple', b = 'banana' } // 所有初始值都是字符串枚举

let e: E = 3  // 可以把任意的number类型赋值给枚举类型,它的取值也可以超出枚举成员的定义
let f: F = 3
e === f // 报错;两种不同的枚举类型成员是不可以比较的

let e1: E.a === 1
let e2: E.b 
e1 === e2 //  报错;两种不同的枚举类型成员是不可以比较的
let e3: E.a === 1
e1 === e3 // true 相同的枚举类型成员可以比较

let g1: G = G.a // 字符串枚举的取值必须是枚举成员的类型
let g2: G.a = G.A // 只能是自身

接口

对象类型接口
  • 接口可以用来约束对象,函数,类的结构和类型,是一种代码协作的契约,必须遵守,且不能改变;
interface List {
    id: number,
    name: string
}
interface Result {
    data: List[]
}

function render(result: Result){
    result.data.forEach((value) => {
        console.log(value.id,value.name)
    })
}

let result = {  // 假设result是从后端返回的接口
    data: [
        {id: 1, name: 'A', sex: 'male'}, // 只要满足要求,传入多余的字段也可以通过类型检查
        {id: 2, name: 'B'}
    ]
}

render(result)  // 没毛病
// 用对象字面量的方式ts会报错
render({  // 假设result是从后端返回的接口
    data: [
        {id: 1, name: 'A', sex: 'male'}, // 只要满足要求,传入多余的字段也可以通过类型检查
        {id: 2, name: 'B'}
    ]
})

绕过这种检查的方式有三种:
1.将对象字面量赋值给一个变量,如上;
2.使用类型断言, as Result,或在前面加上<Result>
    - 这两种方法是等效的,建议使用第一种方法,<Result>在React会产生歧义
明确的告诉编译器,传入的对象类型就是Result,这样编译器就会绕过类型检查
render({  // 假设result是从后端返回的接口
    data: [
        {id: 1, name: 'A', sex: 'male'}, // 只要满足要求,传入多余的字段也可以通过类型检查
        {id: 2, name: 'B'}
    ]
} as Result)

render(<Restul>{  // 假设result是从后端返回的接口
    data: [
        {id: 1, name: 'A', sex: 'male'}, // 只要满足要求,传入多余的字段也可以通过类型检查
        {id: 2, name: 'B'}
    ]
})

3.使用字符串索引签名
interface List {
    id: number,
    name: string,
    [x: string]: any  // 字符串索引签名, 含义是:用任意的字符串去索引List,可以得到任意的结果,这样List可以支持多个属性了
}

接口成员属性:

1. 可选属性,属性后加 ?
interface List {
    id: number,
    name: string,
    age?: number  // 可有可无
}
2. 只读属性
interface List {
    readonly id: number, // id一般是只读属性
    name: string
}

可索引类型的接口

  • 在不确定接口返回来的属性的个数,就可定义可索引类型的接口,可以用数字去索引,也可用字符串去索引
// 数字索引类型的接口
interface StringArray {
    [index: number]: string  // 用任意的数字去索引stringArray,都会得到一个string,就相当于声明了一个字符串类型的数组
}
// 字符串索引类型的接口
interface Names {
    [x: string]: string; // 用任意字符串去索引Names,得到的都是一个string,这样声明后,就不能声明number类型的成员了
    // y: number;  // 不被允许
}
两种索引签名是可以混用的:
interface Names {
    [x: string]: string, // [x: string]: any,
    [z: number]: string  // 注意:数字索引签名的返回值一定要是字符串索引签名返回值的子类型,因为js会进行类型转换,将number转换成string,这样就能保持类型的兼容性
}

转载于:https://my.oschina.net/u/3150996/blog/3080248

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值