TypeScript
定义:Typescript是拥有类型的JavaScript超集 它可以编译成普通,干净,完整的JavaScript代码
我们可以将TypeScript理解成加强版的JavaScript。
JavaScript所拥有的特性,TypeScript全部都是支持的,并且它紧随ECMAScript的标准,所以ES6、ES7、ES8等新语法标准,它都是支持的;
TypeScript在实现新特性的同时,总是保持和ES标准的同步甚至是领先;
并且在语言层面上,不仅仅增加了类型约束,而且包括一些语法的扩展,比如枚举类型(Enum)、元组类型(Tuple)等;
并且TypeScript最终会被编译成JavaScript代码,所以你并不需要担心它的兼容性问题,在编译时也可以不借助于Babel这样的工具;
注意 刚开始学习ts时写.ts文件容易报重复声明的错误 因为不是进行模块化开发 所以建议在每个文件的开头或结尾加上export {}就不会报错了
export {}
TypeScript的编译环境
我们需要在电脑上安装TypeScript,这样就可以通过TypeScript的Compiler将其编译成JavaScript;
安装命令
npm install typescript -g
#查看版本
tsc --version
我们可以使用ts-node快速查看TypeScript代码的运行效果
安装ts-node
npm install ts-node -g
ts-node需要依赖 tslib 和 @types/node 两个包
npm install tslib @types/node -g
我们可以直接通过 ts-node 来运行TypeScript的代码
ts-node .ts文件
变量的声明
在TypeScript中定义变量需要指定标识符的里欸选哪个
声明格式如下
var/let/const 标识符: 数据类型 = 赋值;
声明了类型后TypeScript就会进行类型检测 声明类型可以称之为类型注解
let message: string = 'hello world';
如果我们给message赋值其他类型的值 那么就会报错
声明变量的关键字
在TypeScript定义变量(标识符)和ES6之后一致,可以使用var、let、const来定义。
var name: string = 'kobe'
let age: number = 20
const height: number = 1.90
但是在TypeScript不推荐使用var关键字 主要原因和ES6升级后let和var的区别是一样的,var是没有块级作用域
的
变量的类型推导
在开发中,有时候为了方便起见我们并不会在声明每一个变量时都写上对应的数据类型,我们更希望可以通过TypeScript本身的
特性帮助我们推断出对应的变量类型
这是因为在一个变量第一次赋值时,会根据后面的赋值内容的类型,来推断出变量的类型
number类型
数字类型是我们开发中经常使用的类型,TypeScript和JavaScript一样,不区分整数类型(int)和浮点型(double),统一为
number类型。
let num: number = 10
学习过ES6应该知道,ES6新增了二进制和八进制的表示方法,而TypeScript也是支持二进制、八进制、十六进制的表示:
num = 100 //十进制
num = 0b110 //二进制
num = 0o555 //八进制
num = 0xf23 //十六进制
boolean类型
boolean类型只有两个取值:true和false,非常简单
let flag: boolean = true
flag = false
flag = 20 > 30
string类型
string类型是字符串类型,可以使用单引号或者双引号表示
let message:string = 'hello world'
Array类型
数组类型的定义也非常简单,有两种方式
Array事实上是一种泛型的写法 后面会提到
let names: string[] = ['abc', 'cba', 'nba'];
let nums: Array<number> = [123, 321, 111];
注意事项 数组一般存放相同的类型 不存放不同的类型
如果添加其他类型到数组中,那么会报错
Object类型
object对象类型可以用于描述一个对象:
type是用来声明类型
type InfoType = {
name: string;
age: number;
};
let info: InfoType = {
name: '1231',
age: 1231,
};
Symbol类型
const s1:symbol = Symbol('title')
const s2:symbol = Symbol('title')
const person ={
[s1]:'程序员',
[s2]:'老师'
}
null和undefined类型
在 JavaScript 中,undefined 和 null 是两个基本数据类型。
在TypeScript中,它们各自的类型也是undefined和null,也就意味着它们既是实际的值,也是自己的类型
let n: null = null
let u: undefined = undefined
函数的参数类型
函数是JavaScript非常重要的组成部分,TypeScript允许我们指定函数的参数和返回值的类型。
参数的类型注解
声明函数时,可以在每个参数后添加类型注解,以声明函数接受的参数类型:
function sum(num1: number, num2: number): number {
return num1 + num2;
}
sum(123, 321);
函数的返回值类型
我们也可以添加返回值的类型注解,这个注解出现在函数列表的后面
function sum(num1: number, num2: number): number {
return num1 + num2;
}
const res = sum(123, 321);
和变量的类型注解一样,我们通常情况下不需要返回类型注解,因为TypeScript会根据 return 返回值推断函数的返回类型:
匿名函数的参数
匿名函数与函数声明会有一些不同:
当一个函数出现在TypeScript可以确定该函数会被如何调用的地方时 该函数的参数会自动指定类型;
const names = ['abc', 'cba', 'nba'];
names.forEach(item => {
console.log(item.toUpperCase())
})
我们并没有指定item的类型,但是item是一个string类型:
这是因为TypeScript会根据forEach函数的类型以及数组的类型推断出item的类型;
这个过程称之为上下文类型(contextual typing),因为函数执行的上下文可以帮助确定参数和返回值的类型;
对象类型 与 可选类型
对象类型也可以指定哪些属性是可选的,可以在属性的后面添加一个?:
如果我们希望限定一个函数接受的参数是一个对象,这个时候要如何限定呢
type PointType = {
x: number;
y: number;
z?: number; //可选
};
function printCoordinate(point: PointType) {
console.log('x坐标', point.x);
console.log('y坐标', point.y);
}
printCoordinate({ x: 1, y: 2 });
any类型
在某些情况下,我们确实无法确定一个变量的类型,并且可能它会发生一些变化,这个时候我们可以使用any类型
const arr: any[] = [111, '111', true]
如果对于某些情况的处理过于繁琐不希望添加规定的类型注解,或者在引入一些第三方库时,缺失了类型注解,这个时候我们可
以使用any:包括在Vue源码中,也会使用到any来进行某些类型的适配;
unknow类型
unknown是TypeScript中比较特殊的一种类型,它用于描述类型不确定的变量。
和any类型有点类似,但是unknown类型的值上做任何事情都是不合法的;
要求必须进行类型校验 (缩小) 才能根据缩小后的类型进行对应的操作
let foo: unknown = 'aaa';
if (typeof foo === 'string') {//类型缩小
console.log(foo.length, foo.split(''));
}
直接操作会报错
void类型
void通常用来指定一个函数是没有返回值的,那么它的返回值就是void类型
function sum(num1: number, num2: number): number {
return num1 + num2;
}
这个函数我们没有写任何类型,那么它默认返回值的类型就是void的,我们也可以显示的来指定返回值是void
function sum(num1: number, num2: number): void {
console.log(num1 + num2);
}
我们可以将undefined赋值给void类型,也就是函数可以返回undefined
当基于上下文的类型推导(Contextual Typing)推导出返回类型为 void 的时候,并不会强制函数一定不能返回内容。
type FnType = () => void;
const foo: FnType = () => {
return 123;
};
console.log(foo());
never类型
never 表示永远不会发生值的类型,比如一个函数
如果一个函数中是一个死循环或者抛出一个异常 会推导出never
function foo(): never {
// while (true) {
// console.log('------');
// }
throw new Error('123');
}
foo();
tuple类型
tuple是元组类型,很多语言中也有这种数据类型,比如Python、Swift等
const info: [string, number, number] = ['kobe', 30, 1.88];
const value = info[2];
那么tuple和数组有什么区别呢?
首先,数组中通常建议存放相同类型的元素,不同类型的元素是不推荐放在数组中。(可以放在对象或者元组中)
其次,元组中每个元素都有自己特性的类型,根据索引值获取到的值可以确定对应的类型;
Tuple的应用场景
tuple通常可以作为返回的值,在使用的时候会非常的方便;
例如react的setState钩子函数 就可以使用tuple
// 在函数中使用元组类型是最多的(函数的返回值)
function useState(initialState: number): [number, (newValue: number) => void] {
let stateValue = initialState;
function setValue(newValue: number) {
stateValue = newValue;
//重新渲染组件
}
return [stateValue, setValue];
}
const [count, setCount] = useState(10);