1.简介
- ts 支持类型支持,ts = type +JavaScript。
- ts 和 js 区别
- JavaScript 属于动态编程语言,而ts 属于静态编程语言。
- js:边解释边执行,错误只有在运行的时候才能发现
- ts:先编译再执行,在写的时候就会发现错误了(ts不能直接执行,需要先编译成 js )
- ts 完全支持 js ,可以直接转换
- ts 有类型支持,有强大的代码类型提示
2.安装
npm i -g typescript
或
yarn global add typescript
查看版本
npm -V
3.类型注解
类型注解:给变量添加类型约束,可以显示标记出代码中的意外行为,从而降低了发生错误的可能性。更好的规定了数据的类型,避免了不必要的错误。 语法:
let 变量名: 类型 = 初始值
let age: number = 18
代码错误提示插件:Error Lens
4.ts的类型
-
ts 的常用基础类型分为两种: js 已有类型
- 原始类型:
number/string/boolean/null/undefined/symbol - 对象类型:
object(包括,数组、对象、函数等对象)
- 原始类型:
-
ts 新增类型
- 联合类型
- 自定义类型(类型别名)
- 接口
- 元组
- 字面量类型
- 枚举
- void
- any
- 等等
// 数值类型
let age: number = 18
// 字符串类型
let myName: string = '小花'
// 布尔类型
let isLoading: boolean = false
// undefined
let un: undefined = undefined
// null
let timer:null = null
// symbol
let uniKey:symbol = Symbol()
4.1 symbol原始数据类型
ES6 symbol原始数据类型,表示独一无二的值,最大用法是定义对象的唯一属性名。
Symbol 函数栈不能用 new 命令,因为 Symbol 是原始数据类型,不是对象。可以接受一个字符串作为参数。
let sy = Symbol("KK");
console.log(sy,typeof(sy)); // Symbol(KK)
typeof(sy); // "symbol"
- 作为属性名
let sy = Symbol("key1");
// 写法1
let syObject = {};
syObject[sy] = "kk";
console.log(syObject); // {Symbol(key1): "kk"}
// 写法2
let syObject = {
[sy]: "kk"
};
console.log(syObject); // {Symbol(key1): "kk"}
// 写法3
let syObject = {};
Object.defineProperty(syObject, sy, {value: "kk"});
console.log(syObject); // {Symbol(key1): "kk"}
- 获取对象的值
let syObject = {};
syObject[sy] = "kk";
syObject[sy]; // "kk"
syObject.sy; // undefined 不能用.,要用[],因为.后面是字符串,所以取到的是字符串 sy 属性,而不是 Symbol 值 sy 属性。
- 获取对象的键
Symbol 值作为属性名时,该属性是公有属性不是私有属性,可以在类的外部访问。但是不会出现在 for...in 、 for...of 的循环中,也不会被 Object.keys() 、 Object.getOwnPropertyNames() 返回。如果要读取到一个对象的 Symbol 属性,可以通过 Object.getOwnPropertySymbols() 和 Reflect.ownKeys() 取到。
let syObject = {};
syObject[sy] = "kk";
console.log(syObject);
for (let i in syObject) {
console.log(i);
} // 无输出
Object.keys(syObject); // []
Object.getOwnPropertySymbols(syObject); // [Symbol(key1)]
Reflect.ownKeys(syObject); // [Symbol(key1)]
4.2 联合类型
let 变量: 类型1 | 类型2 | 类型3 .... = 初始值
let arr1 :number | string = 1 // 可以写两个类型
4.3 类型别名
type NewType = string | number
let a: NewType = 1 let b: NewType = '1'
注意:别名可以是任意的合法字符串,一般**首字母大写**
4.4 数组类型
// 写法1:
let 变量: 类型[] = [值1,...]:
let numbers: number[] = [1, 3, 5]
// numbers必须是数组,每个元素都必须是数字
// 写法2:
let 变量: Array<类型> = [值1,...]
let strings: Array<string> = ['a', 'b', 'c']
// strings必须是数组,每个元素都必须是字符串
4.5 函数
函数涉及的类型实际上指的是:函数参数和返回值的类型
- 单个函数
// 普通函数
function 函数名(形参1: 类型=默认值, 形参2:类型=默认值,...): 返回值类型 { }
// 声明式实际写法:
function add(num1: number, num2: number): number {
return num1 + num2
}
// 箭头函数
const 函数名(形参1: 类型=默认值, 形参2:类型=默认值, ...):返回值类型 => { }
const add2 = (a: number =100, b: number = 100): number =>{
return a + b
}
// 注意: 箭头函数的返回值类型要写在参数小括号的后面
add(1,'1') // 报错
- 统一定义函数格式
type Fn = (n1:number,n2:number) => number const add3 : Fn = (a,b)=>{return a+b } // 这样书写起来就简单多啦
- 函数返回值类型void
在 ts 中,如果一个函数没有返回值,应该使用 void 类型
- 函数没写return
- 只写了 return, 没有具体的返回值
- return 的是 undefined
- 函数-可选参数
slice (a?: number, b?: number)
- 默认值
slice (a?: number=0, b?: number=1)
- 对象类型
const 对象名: {
属性名1:类型1,
属性名2?:类型2,
方法名1(形参1: 类型1,形参2: 类型2): 返回值类型,
方法名2:(形参1: 类型1,形参2: 类型2) => 返回值类型
} = { 属性名1: 值1,属性名2:值2 }
- 接口
当一个对象类型被多次使用时,有如下两种方式来来描述对象的类型,以达到复用的目的:
- 类型别名,type
- 接口,interface
接口和类型 的区别 interface(接口)和 type(类型别名)的对比:
-
相同点:都可以给对象指定类型
-
不同点:
- 接口,只能为对象指定类型。它可以继承。
- 类型别名,不仅可以为对象指定类型,实际上可以为任意类型指定别名
// 接口的写法-------------
interface IPerson {
name: string,
age: number
}
const user1:IPerson = {
name: 'a',
age: 20
}
// type的写法-------------
type Person = {
name: string,
age: number
}
const user2:Person = {
name: 'b',
age: 20
}
- 接口继承
interface 接口2 extends 接口1 {
属性1: 类型1, // 接口2中特有的类型
}
interface a { x: number; y: number }
// 继承 a
// 使用 extends(继承)关键字实现了接口
interface b extends a {
z: number
}
// 继承后,b 就有了 a 的所有属性和方法(此时,b 同时有 x、y、z 三个属性)