typescript快速入门之常见类型
基本类型
基本类型就是以下:string、number、boolean、null、undefined、symbol、bigint、object、any
let str:string = 'hello world'
let num:number = 123
let bool:boolean = true
// null是空值,只能赋值给null和undefined
let nul:null = null
// strict:true时,执行的是严格检查,nul不能赋值给undefined
nul = undefined
// undefined是undefined类型,只能赋值给null和undefined
let undef:undefined = undefined
// strict:true时,执行的是严格检查,undef不能赋值给null
undef = null
let sym:symbol = Symbol()
// target设置低于ES2020 时,BigInt 字面量不可用。
let big:bigint = 123n
let obj:object = {name:'zhangsan',age:18}
// any是任意类型,可以赋值任意类型
let a:any = 'hello world'
a = 3
// void是空类型,只能赋值给void
let v:void = undefined
// strict:true时,执行的是严格检查,v不能赋值给null
v = null
// 也可以使用字面量类型
let wd:"world";
// wd = 1 // 报错
wd = "world"
引用类型
数组类型:数组有两种定义方式
// 数组类型:数组有两种定义方式
let arr1:number[] = [1,2,3]
// arr1[3] = 'hi' // 不能将类型“"hi"”分配给类型“number”。
let arr2:Array<number> = [1,2,3]
let strArr: Array<string> = ['hello']
联合类型
联合类型,表示一个变量可以是多个类型
// 联合类型,表示一个变量可以是多个类型
let union:string|number = 'hello world'
union = 123
union = 'hi'
// union = true // 不能将类型“boolean”分配给类型“string | number”。
let union2:string|number|boolean|null = 'hello world'
// 字面量类型和联合类型可以组合使用
let union3:'hello world'|'hi' = 'hello world'
union3 = 'hi'
// union3 = 'hello'// 不能将类型“"world"”分配给类型“"hello world" | "hi"”。
let sex:'男'|'女' = '男'
sex = '女'
数组也能用联合类型
// 下面两种方式是等价的,里面的内容可以是数字或字符串
const arr3:(string|number)[] = ['hello',123, 'world']
const arr4:Array<string|number> = ['hello',123, 'world']
// 下面的跟上面的是不一样的,意思是数组的内容一旦确定是数字或字符串,就只能是相应的类型
const arr5:string[]|number[] = ['hello','world']
// arr5.push(4) // 类型“number”的参数不能赋给类型“string”的参数
// 数组不赋值的话默认是any类型
const arr1 = []
// 元组类型:元组是一个固定长度的数组
let tuple:[string,number] = ['hello world',123]
tuple[0] = 'hi'
tuple[1] = 456
tuple.push(789)
/*
报错是因为 TypeScript 对元组的处理方式不同于普通数组。
tuple.push(789) 可以工作是因为 push 方法是数组的一个方法,它不会检查数组的长度或类型约束。
而直接赋值 tuple[2] = 789 会触发类型检查,因为元组的长度是固定的,且每个位置的类型也是固定的。
*/
// tuple[2] = 789 // error, 不能将类型“789”分配给类型“undefined”
console.log(tuple.length)
// 使用场景:坐标
const position:[number,number] = [21.278, 45.123]
// 下面两种是不一样的,第一个是表示value是个空数组,类型是any;第二个表示是个空元组(never),给空元组赋其它值会报错
let value = []
let value2:[] = []
// value2.push(1) // 类型“1”的参数不能赋给类型“never”的参数
函数
参数不声明类型,TypeScript默认为any类型,可以使用 :类型 来声明参数类型
如果函数没有返回值,默认使用 void 来标记返回值类型,也可以显示的声明
// strict: true 时,参数声明不能为any类型;y要使用add的声明方式
function add2(x:any, y:any): void {
console.log(x + y)
}
function add(x: number, y: number): number {
return x + y;
}
如果参数是可选的,可以使用 ? 来标记可选的参数。注意:可选参数必须要在必选参数后面
function buildName(firstName: string, lastName?: string): string {
if (lastName) {
return firstName + " " + lastName;
} else {
return firstName;
}
}
默认参数: 可以在参数声明后面直接赋值,表示参数默认值
function buildName2(firstName: string, lastName: string = "Smith"): string {
return firstName + " " + lastName;
}
buildName2("Bob"); // Bob Smith
剩余参数: 可以用…来表示,类型为数组
function buildName3(firstName: string, ...restOfName: string[]): string {
return firstName + " " + restOfName.join(" ");
}
buildName3("Joseph", "Samuel", "Lucas", "MacKinzie"); // Joseph Samuel Lucas MacKinzie
泛型:泛型是指在定义函数、接口或类的时候,不预先指定具体的类型,而在使用的时候再指定类型的一种特性
// 这里的T不是固定的,可以使用A-Z都可以,任意的都可以
function identity<T>(arg: T): T {
return arg;
}
// 使用泛型, 也可以不声明类型直接赋值,ts会自动进行类型推断
let output = identity<string>("myString");
// 返回固定的数组值
function identity2<T>(arg: T, arg2: T): [T, T] {
return [arg, arg2];
}
const output2 = identity2<string>('hello', 'world')
// 返回固定的数组值,但里面的参数不一样,可以有多个不同的类型
function identity3<T, U>(arg: T, arg2: U): [T, U] {
return [arg, arg2];
}
// 可以声明一样的
const output3 = identity3('hello', 'world')
// 也可以声明不一样的,默认推导类型;也可以显示的声明类型,给类型添加约束条件
const output4 = identity3<number, string>(1, '元')
console.log(output, output2, output3, output4)
// 案例:泛型的优点不需要声明类型
function myFilter<T>(array: T[], callback: (arg: T, index?: number) => boolean): T[] {
let result: T[] = [];
for (let i = 0; i < array.length; i++) {
if (callback(array[i])) {
result.push(array[i]);
}
}
return result;
}
// 显示声明
const result = myFilter<string>(['a.java', 'index.html', 'index.ts', 'index.js'], item => item.endsWith('.ts'))
// 自动推导
const result2 = myFilter([1, 2, 3, 4, 5, 6], item => item % 2 === 0)
console.log(result, result2)
对象字面量
// 下面两种语法是同等的
// const v4 = 'hello'
const v4:'hello' = 'hello'
// 不显示的声明,对象也会做类型保护
const obj1 = {
id: 1,
name: 'hello',
age: 18
}
// obj1.id = 'hi' // error: 不能将类型“string”分配给类型“number”
// 下面跟上面结果一样,显示的声明类型
const obj2: { id: number; name: string; age: number } = {
id: 1,
name: 'hello',
age: 18
}
// 数组声明
const arr7: { id: number; name: string; age: number }[] = [
{
id: 1,
name: 'hello',
age: 18
},
{
id: 2,
name: 'hi',
age: 19
}
]
// arr7[0].age = 'hi' // 定义了每项的类型,改变类型error: 不能将类型“string”分配给类型“number”
// 下面等同上面的语法,只是两种不同的声明方式
const arr8: Array<{ id: number; name: string; age: number }> = [
{
id: 1,
name: 'hello',
age: 18
},
{
id: 2,
name: 'hi',
age: 19
}
]
函数使用
// 函数使用, 传入对应的类型,返回对应的类型值数组,下面语法可以改成这样
/* function getInfo(user: {name: string, age: number}): {name: string, age: number}[] {
return [
{
name: '张三',
age: 18
},
{
name: '李四',
age: 19
}
]
}
let user = {name: '王五', age: 20 }
getInfo(user) */
// 修改过后
type user = {
name: string,
age: number
}
function getInfo(user: user): user[] { // 这里的user就是上面定义的user类型
return [
{
name: '张三',
age: 18
},
{
name: '李四',
age: 19
}
]
}
getInfo({name: '王五', age: 20})