typeScript-基础篇(二)

  • 建议先从 typeScript从入门到进阶-基础篇(一)开始学习, 基础(一)是一个ts初体验,走完这个流程你本地就拥有了ts的相关环境和编译工具,能够进行下面的语法测试;html

  • 或者也能够在 ts在线编译地址 里面进行下面的语法测试;typescript

基本类型

ES6的数据类型 TS的数据类型
Boolean Boolean
Number Number
String String
Array Array
Function Function
Object Object
Symbol Symbol
undefind undefind
null null
- 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){}
}
枚举类型

一组有名字的常量集合json

  • 枚举成员的值是只读类型的,一旦定义了不能修改
  • 实现原理:反向映射,枚举被编译成了一个对象,枚举成员的名称被做为了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,这样就能保持类型的兼容性
}
相关文章
相关标签/搜索