1.概念
TypeScript 是一种由微软开发的自由和开源的编程语言,它是JavaScript的一个超集,扩展了JavaScript的语法。最主要特点就是对数据类型的校验,方便开发人员更好的管理项目生态。
2.安装
npm install -g typescript
- 在编辑器,将下面的代码输入到test.ts文件里:
// test.ts
function greeter(person) {
return 'Hello, ' + person
}
const user ='violet'
- 在终端执行
tsc test.ts
- 项目目录下会自动生成对应的test.js
// test.js
function greeter(person) {
return 'Hello, ' + person
}
const user ='violet'
3.转换js
项目中会写大量的.ts文件,有什么好的办法能够对整个项目中的ts文件进行转换
1.命令行执行转换
- 在终端执行
tsc --init
- 会自动在目录生成tsconfig.json
{
"compilerOptions": {
/* Basic Options */
// "incremental": true, /* Enable incremental compilation */
"target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */
"module": "commonjs",
/* Advanced Options */
"skipLibCheck": true, /* Skip type checking of declaration files. */
"forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */
}
}
- 在终端执行 tsc,会将所有的ts转换成对应的js
tsc
2.通过vscode 插件转换(开发常用)
- TypeScript Auto Compiler
- Live Server --实时更新
- 保存,会自动生成更新对应的js
4.基本数据类型和报错解析
4.1 基本数据类型
- numbers(数字)
// baseData.ts
let num = 25
/**
* 等同于
* let num: number = 25
*/
// 重新赋值,不能存储非原有的类型数据
// num = '26' // aseData.ts(16,1): error TS2322: Type 'string' is not assignable to type 'number'.
- strings(字符串)
JavaScript程序的另一项基本操作是处理网页或服务器端的文本数据。 像其它语言里一样,我们使用 string表示文本数据类型。 和JavaScript一样,可以使用双引号( ")或单引号(')表示字符串。
let str: string = 'violet'
- boolean(布尔值)
let isLogin = false // 等同于let isLogin:boolean = false
// 更改,赋值为数字改成1,报错,只能赋值为true || false
// isLogin = 1 // baseData.ts(29,1): error TS2322: Type 'number' is not assignable to type 'boolean'.
- any(任意类型)
//任何类型,尽量不要使用
let anything // let anything:any
anything = 25
anything = 'violet'
4.2 元组数组和枚举
- 元组 Tuple
元组类型允许表示一个已知元素数量和类型的数组,各元素的类型不必相同。 比如,你可以定义一对值分别为 string和number类型的元组。
- 注意:类型位置与值一一对应
let colors: [string, number] = ['hello', 99] // 类型与值必须一一对应
- 数组 Array
- 数组字符串类型
// let names = ['hery', 'buky']
let names: Array<string> = ['hery', 'buky']
console.log(names, names[0]) // ["hery", "buky"]0: "hello"1: "buky"length: 2__proto__: Array(0) 'hery'
// names[0] = 100 // .ts(11,1): error TS2322: Type 'string[]' is not assignable to type 'string'.
names[0] = 'hello'
names = ['12233']
console.log(names,names[0]) // ["12233"] "12233"
- 数组数字类型
// 数组里面类型是number
let numbers: Array<number> = [1, 2] // 等同于 let number: number[] = [1, 2]
- 数组任意类型
// 任意类型的数组
let anyArray: any[] = ['violet', 1, false]
console.log(numbers, anyArray, numbers[0]) // [1, 2] ["violet", 1, false] 1
- 枚举(enum)
enum类型是对JavaScript标准数据类型的一个补充。
enum Color {
Black,
Red,
Yellow,
}
let mycolor: Color = Color.Black
console.log(mycolor, 'mycolor') // /0 "mycolor"
- 注意:默认情况下,从0开始为元素编号。 你也可以手动的指定成员的数值,默认是+1
// 手动修改成员值
enum Color {
Black = 2,
Red,
Yellow,
}
let mycolor: Color = Color.Yellow
console.log(mycolor, 'mycolor') //4 "mycolor"
4.3 函数类型
- 规定函数返回值类型
格式:函数名():number
// 规定函数返回值类型是string
function returnValue(): string {
return 'hello'
}
console.log(returnValue()) // hello
- 函数没有返回值的类型
// 无返回值函数类型为空 void
function sayHeool(): void {
console.log('heel0')
}
- 规定参数返回值类型
/**
* @param val1 无类型 默认是any,格式 (参数1:number)
* @param val2 五类线 默认是any
*/
function sumValue(val1: number, val2: number): number {
return val1 + val2 // 如果有一个参数不是number 则返回的值是NAN
}
console.log(sumValue(1, 2)) // 3
- 函数类型
书写完整函数类型
let myAdd: (x: number, y: number) => number =
function(x: number, y: number): number { return x + y; };
let myFunc // 相当于是any 类型
myFunc = sayHeool
myFunc() //heel0
myFunc = sumValue
console.log(myFunc(5, 5)) // 10
// 定义这个函数 参数是number 并且返回值类型也是number
let myFunc1: (a: number, b: number) => number
- 可选参数
在TypeScript里我们可以在参数名旁使用 ?实现可选参数的功能。 比如,我们想让last name是可选的:
// 可选参数和默认参数
function buildName(firstName: string, lastName?: string) {
if (lastName) return firstName + ' ' + lastName
else return firstName
}
let result1 = buildName('violet') // works correctly now
console.log(result1) //violet
// let result2 = buildName('violet', 'kat', 'fly') // error, Expected 1-2 arguments, but got 3.
let result3 = buildName('violet', 'kat')
console.log(result3) // violet,kat
- 注意:可选参数必须跟在必须参数后面
- 与普通可选参数不同的是,带默认值的参数不需要放在必须参数的后面
- 默认参数
在所有必须参数后面的带默认初始化的参数都是可选的,与可选参数一样,在调用函数的时候可以省略。 也就是说可选参数与末尾的默认参数共享参数类型。
function buildName(firstName: string, lastName = '233') {
return firstName + ' ' + lastName
}
let result1 = buildName('violet') // works correctly now
console.log(result1) //violet 233
let result2 = buildName('Bob', undefined)
console.log(result2) //Bob 233
- 剩余参数
必要参数,默认参数和可选参数有个共同点:它们表示某一个参数。
同时操作多个参数,或者你并不知道会有多少参数传递进来。 在JavaScript里,你可以使用 arguments来访问所有传入的参数。
在TypeScript里,你可以把所有参数收集到一个变量里:
function buildName(firstName: string, ...restOfName: string[]) {
return firstName + ' ' + restOfName.join(' ')
}
let employeeName = buildName('violet', 'viole2', 'Lucas', 'MacKinzie')
console.log(employeeName) // 'violet', 'viole2', 'Lucas', 'MacKinzie'
function buildName(firstName: string, ...restOfName: string[]) {
return firstName + ' ' + restOfName.join(' ')
}
// 函数类型
let buildNameFun: (fname: string, ...rest: string[]) => string = buildName
console.log(buildNameFun('violet1', 'violet2', 'viole3')) // violet1, violet2, viole3
4.4 对象类型和type
let dataObj = {
name: 'viole',
age: 18,
}
// dataObj = {} // error
// dataObj = {
// a: 'hello',
// b: 12,
// }
- 在ts中,定义的对象等同于下面的完整类型
// 完整类型
let dataObj: { name: String; age: number } = {
name: 'viole',
age: 18,
}
dataObj = {
name: 'hello',
age: 12,
}
- 复杂对象类型
let complex: { data: number[]; myFunc: (item: number) => number[] } = {
data: [1, 2, 3],
myFunc: function (item: number): number[] {
this.data.push(item)
return this.data
},
}
console.log(complex.myFunc) // ƒ (item) {this.data.push(item);return this.data}
console.log(complex.myFunc(3)) // [1,2,3,3]
- 使用type
type 来简化复杂数据类型,可以生产自己的类型
// 定义一个私有类型MyType
type MyType = { data: number[]; myFunc: (item: number) => number[] }
let complex2: MyType = {
data: [1, 2, 3],
myFunc: function (item: number): number[] {
this.data.push(item)
return this.data
},
}
console.log(complex2.myFunc(40)) // [1,2,3,40]
4.5 检查类型和其他特殊类型
- union type(联合类型)
如果一个变量在声明时可以有几个不同的类型,需要跟据运行时所传入的参数不同而改变相应类型,这个时候可以使用union type
// 类似于任意类型
let unionType: any = 12
unionType = '12'
// 可以是number 或者string 或者boolean
let unionType: number | string | boolean = 12
unionType = true
- 检查类型(typeof)
以使用typeof判断变量类型一般为number,boolean,string,function,object,undefined这几种之一
如使用typeof来推断一个变量类型:
let checkType = 10
// 注意类型要用引号引起来
if (typeof checkType === 'number') {
console.log('number') // number
}
- null和undefined
TypeScript里,undefined和null两者各自有自己的类型分别叫做undefined和null。 和 void相似,它们的本身的类型用处不是很大:
- 当tsconfig中strict值为true,不能将其他任何类型赋值给null ,undefined
let myNull = 12
myNull = null // 会报错
- 当tsconfig中strict值为false
可以给其他任何类型都赋值给null ,undefined
let myNull = null
myNull = undefined
- never
- neve任何类型是任何类型的子类型,也可以赋值给任何类型
// 将number其他类型 赋值给never
let y: number
y = (() => {
throw new Error('message')
})()
- 没有类型是never的子类型或可以赋值给never类型(除never本身之外)
即使any也不可以赋值给never.
let x: never
x = 123 // error 不能将其他类型转为never
- 应用场景
通常表现为抛出异常或无法执行到终止点(例如无线循环)
// never应用场景,抛出异常
function error(message: string): never {
throw new Error(message)
}
// 死循环
function loop(): never {
while (true) {}
}
// 推断的返回值类型为never
function fail() {
return error('Something failed')
}
4.5 数据类型总结练习
let sumValues = {
money: 200,
count(value) {
this.money += value
},
}
let handleCount= {
name: 'Henry',
sumValues: sumValues,
friends: ['violet', 'elyse'],
}
handleCount.sumValues.count(500)
console.log(handleCount)
- 添加上类型
// object 对象 要看属性
// 重复的类型提取出来
type objeTyep = { money: number; count: (item: number) => void }
let sumValues: objeTyep = {
money: 200,
count(value: number): void {
this.money += value
},
}
let handleCount: {
name: string
sumValues: objeTyep
friends: String[]
} = {
name: 'Henry',
sumValues: sumValues,
friends: ['violet', 'elyse'],
}
handleCount.sumValues.count(500)
console.log(handleCount)
/**
* {name: "Henry", sumValues: {…}, friends: Array(2)}
friends: (2) ["violet", "elyse"]
name: "Henry"
sumValues:
count: ƒ (value)
money: 700
__proto__: Object
__proto__: Object
*/