TypeScript 基础

67 阅读7分钟

一、typescript基础类型

1.TypeScript 简介

TS是JS的超集,所以JS基础的类型都包含在内

基础类型:Boolean、Number、String、null、undefined 以及 ES6 的 Symbol 和 ES10 的 BigInt。

2.学习 TS 必须要知道的命令

# 起步安装 
npm install typescript -g

# 创建 TS 配置文件
tsc --init

# 实时编译 会在同文件夹下创建同名 JS 文件
tsc -w

# 用 node 运行 TS 编译后生成的 JS 文件
node index.js

# 编译 TS 文件为 JS 文件
tsc 文件名

# nodejs 环境执行ts
npm i @types/node --save-dev #(node环境支持的依赖必装)

# 安装
npm i ts-node --g

# 编译并同时运行 TS 文件
ts-node 文件名

3.字符串类型

let a: string = '123'
// 普通声明
 
// 也可以使用es6的字符串模板
let str: string = `dddd${a}`

其中用来定义 [ES6 中的模板字符串],${expr} 用来在模板字符串中嵌入表达式。

4.数字类型

支持十六进制、十进制、八进制和二进制;

let notANumber: number = NaN; // Nan
let num: number = 123; // 普通数字
let infinityNumber: number = Infinity; // 无穷大
let decimal: number = 6; // 十进制
let hex: number = 0xf00d; // 十六进制
let binary: number = 0b1010; // 二进制
let octal: number = 0o744; // 八进制

5.布尔类型

注意,使用构造函数 Boolean 创造的对象不是布尔值:

let createdBoolean: boolean = new Boolean(1)
// 这样会报错 
// 因为事实上 new Boolean() 返回的是一个 Boolean 对象 

事实上 new Boolean() 返回的是一个 Boolean 对象 需要改成

let createdBoolean: Boolean = new Boolean(1)
let booleand: boolean = true // 可以直接使用布尔值

let booleand2: boolean = Boolean(1) // 也可以通过函数返回布尔值

6.空值类型

JavaScript 没有空值(Void)的概念,在 TypeScript 中,可以用 void 表示没有任何返回值的函数

function voidFn(): void {
    console.log('test void')
}

void 类型的用法,主要是用在我们不希望调用者关心函数返回值的情况下,比如通常的异步回调函数

void也可以定义undefined 和 null类型

let u: void = undefined
let n: void = null;

7.Null和undefined类型

let u: undefined = undefined; // 定义undefined
let n: null = null; // 定义null

void 和 undefined 和 null 最大的区别: 与 void 的区别是,undefined 和 null 是所有类型的子类型。也就是说 undefined 类型的变量,可以赋值给 string 类型的变量:

// 这样写会报错 void类型不可以分给其他类型
let test: void = undefined
let num2: string = "1"

num2 = test
// 这样是没问题的
let test: null = null
let num2: string = "1"

num2 = test

// 或者这样的
let test: undefined = undefined
let num2: string = "1"

num2 = test

TIPS 注意: 如果你配置了tsconfig.json 开启了严格模式

{
    "compilerOptions":{
        "strict": true
    }
}

null 不能赋予 void 类型

二、任意类型

1.any 类型

没有强制限定哪种类型,随时切换类型都可以 我们可以对 any 进行任何操作,不需要检查类型

let anys:any = 123
anys = '123'
anys = true

声明变量的时候没有指定任意类型默认为any

let anys;
anys = '123'
anys = true

弊端如果使用any 就失去了TS类型检测的作用

2.unknown 顶级类型

TypeScript 3.0中引入的 unknown 类型也被认为是 top type ,但它更安全。与 any 一样,所有类型都可以分配给unknown

unknow类型比any更加严格当你要使用any 的时候可以尝试使用unknow

// unknown 可以定义任何类型的值
let value: unknown;

value = true;             // OK
value = 42;               // OK
value = "Hello World";    // OK
value = [];               // OK
value = {};               // OK
value = null;             // OK
value = undefined;        // OK
value = Symbol("type");   // OK

// 这样写会报错 unknow 类型不能作为子类型只能作为父类型 any 可以作为父类型和子类型
// unknown 类型不能赋值给其他类型
let names:unknown = '123'
let names2:string = names

// 这样就没问题 any 类型是可以的
let names:any = '123'
let names2:string = names   

// unknown 可赋值对象只有 unknown 和 any
let bbb:unknown = '123'
let aaa:any= '456'

aaa = bbb

区别2

// 如果是 any 类型在对象没有这个属性的时候还在获取是不会报错的
let obj:any = {b:1}
obj.a

// 如果是 unknow 是不能调用属性和方法
let obj:unknown = {b:1,ccc:():number=>213}
obj.b
obj.ccc()

三、接口和对象类型

1.对象的类型

在 TypeScript 中,我们定义对象的方式要用关键字 interface(接口),我的理解是使用 interface 来定义一种约束,让数据的结构满足约束的格式。定义方式如下:

// 这样写是会报错的 因为我们在person定义了a,b但是对象里面缺少b属性
// 使用接口约束的时候不能多一个属性也不能少一个属性
// 必须与接口保持一致
interface Person {
    b:string,
    a:string
}

const person:Person  = {
    a:"213"
}
// 重名interface  可以合并
interface A{name:string}
interface A{age:number}
var x:A={name:'xx',age:20}
// 继承
interface A{
    name:string
}

interface B extends A{
    age:number
}

let obj:B = {
    age:18,
    name:"string"
}

2.可选属性 使用 ? 操作符

// 可选属性的含义是该属性可以不存在
// 所以说这样写也是没问题的
interface Person {
    b?:string,
    a:string
}

const person:Person  = {
    a:"213"
}

3.任意属性 [propName: string]

需要注意的是,一旦定义了任意属性,那么确定属性和可选属性的类型都必须是它的类型的子集:

// 在这个例子当中我们看到接口中并没有定义C但是并没有报错
// 应为我们定义了[propName: string]: any;
// 允许添加新的任意属性
interface Person {
    b?:string,
    a:string,
	[propName: string]: any;
}

const person:Person  = {
    a:"213",
    c:"123"
}

4.只读属性 readonly

readonly 只读属性是不允许被赋值的只能读取

// 这样写是会报错的
// 应为a是只读的不允许重新赋值
interface Person {
    b?: string,
    readonly a: string,
	[propName: string]: any;
}

const person: Person = {
    a: "213",
    c: "123"
}

person.a = 123

5.添加函数

interface Person {
    b?: string,
    readonly a: string,
	[propName: string]: any;
    cb:()=>void
}

const person: Person = {
    a: "213",
    c: "123",
    cb:()=>{
        console.log(123)
    }
}

四、数组类型

1.基础写法[ ]

// 类型加中括号
let arr:number[] = [123]
// 这样会报错定义了数字类型出现字符串是不允许的
let arr:number[] = [1,2,3,'1']
// 操作方法添加也是不允许的
let arr:number[] = [1,2,3,]
arr.unshift('1')

var arr: number[] = [1, 2, 3]; // 数字类型的数组
var arr2: string[] = ["1", "2"]; // 字符串类型的数组
var arr3: any[] = [1, "2", true]; // 任意类型的数组

2.数组泛型

// 规则 Array<类型>
let arr:Array<number> = [1,2,3,4,5]

3.用接口表示数组

// 一般用来描述类数组 
interface NumberArray {
	[index: number]: number;
}
let fibonacci: NumberArray = [1, 1, 2, 3, 5];
// 表示:只要索引的类型是数字时,那么值的类型必须是数字。

4.多维数组

let data:number[][] = [[1,2], [3,4]];

5.arguments类数组

function Arr(...args:any): void {
    console.log(arguments)
    // 错误的arguments 是类数组不能这样定义
    let arr:number[] = arguments
}
Arr(111, 222, 333) 

function Arr(...args:any): void {
    console.log(arguments) 
    // ts内置对象IArguments 定义
    let arr:IArguments = arguments
}
Arr(111, 222, 333)

// 其中 IArguments 是 TypeScript 中定义好了的类型,它实际上就是:
interface IArguments {
    [index: number]: any;
    length: number;
    callee: Function;
}

6.any 在数组中的应用

// 一个常见的例子数组中可以存在任意类型
let list: any[] = ['test', 1, [],{a:1}]

五、函数扩展

1.函数的类型

// 注意,参数不能多传,也不能少传 必须按照约定的类型来
const fn = (name: string, age:number): string => {
    return name + age
}
fn('张三',18)

2.函数的可选参数?

// 通过?表示该参数为可选参数
const fn = (name: string, age?:number): string => {
    return name + age
}
fn('张三')

3.函数参数的默认值

const fn = (name: string = "我是默认值"): string => {
    return name
}
fn()

4.接口定义函数

//定义参数 num 和 num2  :后面定义返回值的类型
interface Add {
    (num:  number, num2: number): number
}

const fn: Add = (num: number, num2: number): number => {
    return num + num2
}
fn(5, 5)

interface User{
    name: string;
    age: number;
}
function getUserInfo(user: User): User {
  return user
}

5.定义剩余参数

const fn = (array:number[],...items:any[]):any[] => {
       console.log(array,items)
       return items
}

let a:number[] = [1,2,3]

fn(a,'4','5','6')

6.函数重载

重载是方法名字相同,而参数不同,返回类型可以相同也可以不同。

如果参数类型不同,则参数类型应设置为 any。

参数数量不同你可以将不同的参数设置为可选。

function fn(params: number): void

function fn(params: string, params2: number): void

function fn(params: any, params2?: any): void {

    console.log(params)

    console.log(params2)

}

 

fn(123)

fn('123',456)