前言:为什么要学习typescript?首先TypeScript是JavaScript的超集,用于解决大型项目的代码复杂性,且TypeScript是强类型语言,支持静态和动态类型,它在编译期间可以发现并纠正错误,且不允许改变变量的数据类型。
我是学前端一年左右的小白,之前也学习了js和ts,没做过什么项目,不过在实践方面二者都有简单接触过,之前做的pc端页面基本是使用js开发,而接触的同一个项目的移动端是使用ts开发,所以也有点好奇二者有什么区别
以下是通过查找资料以及个人实践的一些体会:
- 移动端对资源的占用要求比pc端更高,需要更高效的代码语言来减少资源占用。
- 移动端设备类型和操作系统非常多样化,使用强类型的TypeScript可以避免很多潜在的兼容性问题。
- 移动端设备的输入方式和屏幕尺寸与pc端有很大差异,需要更强的类型检查来避免出现UI错误等问题。
其实,TypeScriptTypeScript 可以适用于任何 JavaScript 应用场景,并且在大型、复杂的应用程序中发挥着更大的作用
TypeScript基础
基础类型
ts的基础类型有:Boolean、number、string、undefined、null、any、unknown、never
在ts中,声明变量时必须声明变量的数据类型。在没有声明数据类型的情况下,若是声明时给变量赋值,则该变量会默认为该值的类型,若没有赋值,则变量类型默认为any。
any表示“任意值”,即可以赋值给任何类型的变量,也可以由其它类型的变量复制得到。使用any类可以绕过类型检查。在某些情况下,可以使用any类型来处理一些不确定类型的值,比如在使用第三方库时,又是不确定返回值是什么类型,可以使用any来避免编译器报错 (在我之前的开发过程中,调用第三方库时就曾因为返回值不确定总是报错,所以暂时使用any来避免错误,当然后面确定之后最好还是改过来),过度使用any类型会导致编程时类型不明确,调试和重构时比较困难,所以建议在不得已的情况下再使用any。例如:
let a;//a:any
a='a';//没有报错,可以复制为string
a=1;//没有报错,可以赋值给number
let b=0;//b:number
b='b';//不能将类型“string”分配给类型“number”。ts(2322)
//正常声明变量
let animal:string = 'dog';//声明一个变量animal,类型为string
其他类型
Array
ts中的数组可以表示一个由相同类型元素组成的一维数组或多维数组,语法为:type[] 或 Array[]
let arr:string[]=['apple','watermelon'];
let arr1:Array<string>=['foo','bar'];
支持使用push、pop、shift、unshift等方法操作数组,但只能往数组中添加相同类型的元素,否则会报错。
let arr = [1, 2, 3, 4]
arr.push(5)
console.log(arr)//[1,2,3,4,5]
arr.push('a');//报错:类型“string”的参数不能赋给类型“number”的参数
可以使用泛型来表示多种数据类型组成的数组:
let arr1:Array<string|number>=[1,2,'a','b']
元组Tuple
元组(Tuple)类型是typescript中比较特殊的类型,可以看作一种数组类型,但与数组不同的是,元组中的每个元素可以是不同类型的。
声明元组方式与数组类似,不过需要指定每个元素的类型,用逗号隔开,也可以使用类型别名定义。在初始化元组或给元组赋值时,元素数量必须和类型保持一致,否则会导致类型错误。访问元组方式与数组类似,使用索引来访问,也支持push、pop、shift、unshift等方法操作元组,但只能往元组中添加与以由元素类型一致的元素,否则会导致类型错误。以下是定义元组的示例以及一些可能错误:
let tuple: [string, number] = ['hello', 1]
tuple.push(2)
tuple.push('world')
tuple.push(true)//类型“boolean”的参数不能赋给类型“string | number”的参数。ts(2345)
let tuple1: [string, number]=[1,'a'];//不能将类型“number”分配给类型“string”,不能将类型“string”分配给类型“number”
函数类型
ts定义函数类型时要定义输入参数类型和输出参数类型
输入参数支持可选参数和默认参数
输出参数可以自动挡推断,没有返回值时默认为void类型
函数重载:名称相同但参数不同,可以通过重载支持多种类型
//sex为可选参数
function getPerson(name: string, age: number, sex?: string): string{
if (sex) {
return `${name} is ${age} years old,${sex}`
} else {
return `${name} is ${age} years old`
}
}
function add(x:number[]):number
function add(x:string[]):string
function add(x:any[]):any{
if(typeof x[0]==='string'){
return x.join()
}
if(typeof x[0]==='number'){
return x.reduce((acc,cur)=>acc+cur)
}
}
interface(接口)
TypeScript中的interface用于描述对象的数据结构
特点:
- 可选参数:?
- 只读属性:readonly
- 可以描述函数类型
- 可以描述自定义属性
interface Person{
name:string;
age:number;
sex?:string;
sayHello:()=>void;
}
const Tom:Person={
name:'Tom',
age:18,
sayHello:()=>console.log('Hello!')
};//由于sex是可选参数,这里可以不添加sex属性
使用接口可以让ts在编译时捕获一些错误,如给age赋值时赋值类型为字符串,或者忘记初始化某个值。
TS进阶-高级类型
- 联合类型 |
可以使用 | ,使一个变量可以被赋予多种类型
let p:num |string; p=8; p='eight';
- 交叉类型&
交叉类型是通过使用“&”运算符将多个类型组合在一起,表示一个值必须具备同时满足多个类型的属性和方法。例如,如果有两个类型T1和T2,则可以通过以下方式创建一个交叉类型: T1 & T2。这意味着该类型的值必须同时满足类型T1和类型T2的属性和方法.
interface People{ firstname: string age: number } type Student = People & { sex: string } const stu: Student = { firstname: 'zhao', age: 17, sex:'female' }
- 类型断言
允许手动指定一个值的类型,并告诉编译器这个类型是正确的,语法:
<Type>valuevalue as Typelet str: number | string = 'hello' `let len: number = (<string>str).length let len1: number = (str as string).length以上例子,通过类型断言,将str视为string类型,并调用该类型的length属性,若没有该类型断言,则有可能会报错
泛型
泛型是一种将类型参数化的技术,可以在编写代码时提供更好的灵活性和类型安全。使用泛型,可以编写独立于类型的代码,然后在需要的时候指定类型参数
functon print<T>(arg:T):T{
console.log(arg)
return arg
}
print('hello')//类型断言,推断类型为string
print(1)//T为number
泛型工具类型-基础操作符
- typeof:获取类型
- keyof:获取所有键
- in:遍历枚举类型
- T[K]:索引访问
- extends:泛型约束
最后,关于ts,感觉目前学习的东西还是比较浅的,具体还是要多在项目中练手,才能知道一些知识点的具体用法以及它的好处。