TypeScript的简介
typeScript
TypeScript官网:TypeScript is a typed superset of JavaScript that compiles to plain JavaScript.
GitHub说法:TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
翻译一下:TypeScript
是拥有类型的JavaScript
超集,它可以编译成普通、干净、完整的JavaScript
代码
理解官网的这句话:
TypeScript
(简称ts)是JavaScript
(简称js)的加强版;TypeScript
最终会被编译成JavaScript
来运行,所以我们需要搭建对应的环境;
我们需要在电脑上安装TypeScript
,这样就可以通过TypeScript
的Compiler
将其编译成JavaScript
;
# 安装命令 npm install typescript -g
# 查看版本 tsc --version
俩种解决方案来配置查看运行:
npm install ts-node -g
npm install tslib @types/node -g
ts-node math.ts
在TypeScript中定义变量需要指定 标识符
的类型。 所以完整的声明格式如下:
// 根据定义的数据类型赋值
var/let/const 标识符: 数据类型 = 赋值;
const name:string = 'wendy';
上面说过是支持JavaScript
的模式定义,也可不进行数据类型的添加,但typescript
本身的特性帮助我们推断出对应的变量类型;
如下方的name
起初赋值string
类型后,不可更改为非string
类型
JavaScript
和TypeScript
的数据类型JavaScript
和TypeScript
的数据类型之间的包含关系:
const list1:string[] = ['1', '22']; // 推荐使用
const list2:Array<string> = ['1', '22']; // 在react中时常会有的写法,以免冲突
// any类型有点像一种讨巧的TypeScript手段,就是不定义类型,任何类型都可实现
let name:any = 'wendy';
name = 'Bond';
name = 14555;
name = true;
// unknown是TypeScript中比较特殊的一种类型,它用于描述类型不确定的变量;
// 相对于any ,只有在针对unknown进行类型安全检测之后,才可以允许执行特定的操作。
let score: unknown = 98;
let num = Math.round(score); //error
在没有对它进行类型检查之前,ubnknow
类型的变量是不能进行任何操作的。let score: unknown = 98;
if(typeof score === "number") {
let num = Math.round(score); // ok
}
// 函数没有返回值的类型;
function sum(num1: number, num2: number): void {
console.log(num1 + num2);
}
// 提前
// 封装一个核心函数
function handleMessage(message: string | number | boolean) {
switch (typeof message) {
case 'string':
console.log("string处理方式处理message")
break;
case 'number':
console.log("number处理方式处理message")
break
case 'boolean':
console.log("boolean处理方式处理message")
break
default:
const check: never = message
}
}
// 抛出错误的函数
function loopErr(): never {
throw new Error();
}
const tInfo: [string, number, number] = ["why", 18, 18];
const item1 = tInfo[0]; // why,并可知类型是string类型
const item2 = tInfo[1]; // 18,并可知类型是number
tuple
和Array
数组的区别:const info:(string|number)[] = ["why", 18, 18];
const item1 = info[0]; // 不能确定类型
const tInfo: [string, number, number] = ["why", 18, 18];
const item2 = tInfo[0]; // 一定时string类型
自动推导类型:
// 给参数加上类型注解: num1: number, num2: number
// 给返回值加上类型注释: (): number
// 在开发中,通常情况下可以不写返回值的类型(自动推导)
function sum(num1: number, num2: number) {
return num1 + num2
}
sum(123, 321); // 推导出的类型是number
const names = ["abc", "cba", "nba"]
// item根据上下文的环境推导出来的, 这个时候可以不添加的类型注解
// 上下文中的函数: 可以不添加类型注解
names.forEach(function(item) {
console.log(item.split(""))
})
// Point: x/y -> 对象类型
// {x: number, y: number}
function printPoint(point: {x: number, y: number}) {
console.log(point.x);
console.log(point.y)
}
printPoint({x: 123, y: 321})
可选类型的使用:?
// Point: x/y/z -> 对象类型
// {x: number, y: number, z?: number}
function printPoint(point: {x: number, y: number, z?: number}) {
console.log(point.x)
console.log(point.y)
console.log(point.z)
}
printPoint({x: 123, y: 321})
printPoint({x: 123, y: 321, z: 111})
联合类型的使用: |
// number|string 联合类型
function printID(id: number|string|boolean) {
// 使用联合类型的值时, 需要特别的小心
// narrow: 缩小
if (typeof id === 'string') {
// TypeScript帮助确定id一定是string类型
console.log(id.toUpperCase())
} else {
console.log(id)
}
}
printID(123)
printID("abc")
printID(true)
可选类型与对象类型的关系:
// 当一个参数一个可选类型的时候, 这个参数等价于:类型|undefined 的联合类型
// message?: string 等同于 message: string | undefined
function foo(message?: string) {
console.log(message)
}
类型别名的使用,使用type
的关键字去定义:
// type用于定义类型别名(type alias)
type IDType = string | number | boolean
type PointType = {
x: number
y: number
z?: number
}
function printId(id: IDType) {
}
function printPoint(point: PointType) {
}
as()
;联合类型
,any
,及父子类
之间的断言,通常这会发生在你清楚地知道一个实体具有比它现有类型更确切的类型;有两种书写的形式:
value as type
value
let data : any = "Hello";
let len : number = (<string>data).length;
console.log(len);//输出5
len = (data as string).length;
console.log(len);//输出5
使用示例:
// 1.类型断言 as
const el = document.getElementById("why") as HTMLImageElement
el.src = "url地址"
// 2.另外案例: Person是Student的父类
class Person {
}
class Student extends Person {
studying() {
}
}
function sayHello(p: Person) {
(p as Student).studying()
}
const stu = new Student()
sayHello(stu)
// 3.了解: as any/unknown
const message = "Hello World"
const num: number = (message as unknown) as number
!
// message? -> undefined | string
function printMessageLength(message?: string) {
// 当传入的值是underfind时,时不能执行,编译会报错
// console.log(message.length)
// if (message) {
// console.log(message.length)
// }
// vue3源码
console.log(message!.length)
}
printMessageLength("aaaa")
printMessageLength("hello world")
?
// ? 代码非必传选项
type Person = {
name: string
friend?: {
name: string
age?: number,
girlFriend?: {
name: string
}
}
}
const info: Person = {
name: "why",
friend: {
name: "kobe",
girlFriend: {
name: "lily"
}
}
}
console.log(info.name)
// console.log(info.friend!.name)
console.log(info.friend?.name)
console.log(info.friend?.girlFriend?.name)
Boolean
类型,类似于Boolean
的方式null
或undefined
时,返回右侧的操作数,否则返回左侧的操作数;相当于Boolean
中的&&;const message = '';
const flag1 = Boolean(message); // false
const flag2 = !!message; // false
const flag3 = message ?? '验证失败'; // 验证失败
字面量的基本使用:
// "Hello World"也是可以作为类型的, 叫做字面量类型
const message: "Hello World" = "Hello World"
// let num: 123 = 123
// num = 321
字面量类型的意义, 就是必须结合联合类型
type Alignment = 'left' | 'right' | 'center';
let align: Alignment = 'left';
align = 'right';
align = 'center';
// align = 'hehehehe'; error
字面量推理:
我们来看下面的代码,会出现一个代码检测的错误:
这是因为我们的对象在进行字面量推理的时候,info其实是{ url: string, method: string }
,所以我们没办法将一个string赋值给一个字面量类型;
// 方式一:
request(options.url, options.method as 'POST')
使用as const
的方式
You can use as const to convert the entire object to be type literals:
翻译:你可以使用const将整个对象转换为类型字面量
点击翻看其他释意
// 方式二:使用as const的方式
type Method = 'GET' | 'POST'
function request(url: string, method: Method) {}
type Request = {
url: string,
method: Method
}
const options = {
url: "https://baidu********",
method: "POST"
} as const;
request(options.url, options.method)
相当于多一层的判断该变量的类型进行执行不同的路径,就好比:typeof padding === "number"
的判断语句,来改变TypeScript的执行路径;而我们编写的 typeof padding === "number
可以称之为 类型保护(type guards);
常见的类型保护有如下几种:
typeof
type IDType = number | string
function printID(id: IDType) {
if (typeof id === 'string') {
console.log(id.toUpperCase())
} else {
console.log(id)
}
}
平等缩小(比如===
、!==
)
type Direction = "left" | "right" | "top" | "bottom"
function printDirection(direction: Direction) {
// 1.if判断
if (direction === 'left') {
console.log(direction)
} else if ()
// 2.switch判断
// switch (direction) {
// case 'left':
// console.log(direction)
// break;
// case ...
// }
}
instanceof
// instanceof判断是否是Date的类型,而去执行toUTCString()方法
function printTime(time: string | Date) {
if (time instanceof Date) {
console.log(time.toUTCString())
} else {
console.log(time)
}
}
in
type Fish = {
swimming: () => void
}
type Dog = {
running: () => void
}
function walk(animal: Fish | Dog) {
if ('swimming' in animal) {
animal.swimming()
} else {
animal.running()
}
}
const fish: Fish = {
swimming() {
console.log("swimming")
}
}
walk(fish)
…等