为什么学TS
| TypeScript | JavaScript |
|---|---|
| 强类型,支持静态和动态类型 | 一种脚本语言,用于创建动态网页 |
| JavaScript 的超集,用于解决大型项目的代码复杂性 | 动态弱类型语言 |
| 可以在编译期间发现并纠正错误 | 只能在运行时发现错误 |
| 不允许改变变量的数据类型 | 变量可以被赋值成不同类型 |
TS基础
基础类型
- boolean、number、string
- undefined、null
- any、unknown、void
- never
- 数组类型
- 元组类型 tuple
function test(x: string l number): boolean {
if (typeof x === 'string') {
return true;
} else if (typeof x === 'number') {
return false;
}
return throwError('参数格式不对');
}
function throwError(message:string): never{
throw new Error(message);
}
函数类型
- 定义:TS定义函数类型时要定义输入参数类型和输出类型
- 输入参数:参数支持可选参数和默认参数
- 输出参数:输出可以自动推断,没有返回值时,默认为void类型
- 函数重载:名称相同但参数不同,可以通过重载支持多种类型
function add(x: number[]): number
function add(x: string[]): string
function add(x: any[]): any {
if (typeof x[e] === 'string') {
return x.join()
}
if (typeof x[0] === 'number') {
return x.reduce((acc,cur)=>acc + cur)
}
}
interface
- 定义:接口是为了定义对象类型
- 特点:
- 可选属性: ?
- 只读属性: readonly
- 可以描述函数类型
- 可以描述自定义属性
- 总结:接口非常灵活 duck typing
interface RandomKey {
[propName: string]: string
}
const obj: RandomKey = {
a: 'hello',
b:'world',
c:'typescript'
}
类
定义:写法和JS差不多,增加了一些定义
特点:
- 增加了 public、private、protected 修饰符
-抽象类:
- 只能被继承,不能被实例化
- 作为基类,抽象方法必须被子类实现
- interface约束类,使用implements关键字
进阶
- 联合类型 |
let num:string | number
num=8;
num='string';
- 交叉类型 &
interface Person{
name:string,
age:number
}
type Student=Person & {grade:number}
const stu:Student
stu.grade=20
- 类型断言
function getLength(arg :number | string):number{
const str=arg as string
if(str.length){
return str.length
}else{
const number=arg as number
returtn number.toString().length
}
}
- 类型别名(type interface)
- 定义:给类型起个别名
- 相同点:
- 都可以定义对象或函数
- 都允许继承
- 差异点:
- interface是TS用来定义对象,type是用来定义别名方便使用
- type可以定义基本类型,interface不行;
- interface可以合并重复声明,type不行;
这里我还是对type和interface的区别不是很清楚,所以我去找了篇文章看了下,发现了以下区别点,大家可以看下
相同点
type exampleType1 = {
name: string
}
interface exampleInterface1 {
name: string
}
type exampleType2 = exampleType1 & {
age: number
}
type exampleType2 = exampleInterface1 & {
age: number
}
interface exampleInterface2 extends exampleType1 {
age: number
}
interface exampleInterface2 extends exampleInterface1 {
age: number
}
可以看到对于interface来说,继承是通过 extends 实现的,而type的话是通过 & 来实现的,也可以叫做 交叉类型
还有一种情况需要注意,示例如下
type exampleType1 = {
name: string
}
interface exampleInterface1 {
name: string
}
// 会报错,对于同一个属性,其类型必须一致
interface exampleInterface2 extends exampleInterface1 {
name: number
}
interface exampleInterface2 extends exampleType1 {
name: number
}
//不会报错,但是number和string进行交叉后,得到的是never,因此name属性的类型会变成never
type exampleType2 = exampleInterface1 & {
name: number
}
type exampleType2 = exampleType1 & {
name: number
}
不同点
-
type可以定义 基本类型的别名,如
type myString = string -
type可以通过 typeof 操作符来定义,如
type myType = typeof someObj -
type可以申明 联合类型,如
type unionType = myType1 | myType2 -
type可以申明 元组类型,如
type yuanzu = [myType1, myType2]
以下说说interface可以做到,但是type不可以做到的事情
- interface可以 声明合并
interface test {
name: string
}
interface test {
age: number
}
/*
test实际为 {
name: string
age: number
}
*/
这种情况下,如果是type的话,就会报 重复定义 的警告,因此是无法实现 声明合并 的
还有一种情况需要注意
/*
会报错,如果重复定义同一个属性,其类型必须相同
*/
interface test {
name: string
}
interface test {
name: number
}
通过以上,我对type和interface的区别也更加清楚了
泛型
基本定义
- 泛型的语法是>里面写类型参数,一般用T表示
- 使用时有两种方法指定类型:
- 定义要使用的类型
- 通过TS类型推断,自动推导类型
- 泛型的作用是临时占位,之后通过传来的类型进行推导
function print<T>(arg:T):T {
console.log(arg)
return arg
}
print<string>('hello') // 定义T为 string
print('heLlo') // TS 类型推断,自动推导类型为 string
基本操作符
- typeof:获取类型
interface Person{
name:string;
age:number;
}
const sem:Person={name:'nike',age:30}
type Sem= typeof sem;//type Sem =Person
- keyof: 获取所有键
interface Person{
name:string;
age:number;
}
type H1=keyof Person;//"name" | "age"
type H2=keyof Person[];//"length" | "toString" | "pop" | "push" | "concat" | "join"
- in:遍历枚举类型
type Keys="a" | "b" | "c"
type Obj={
[p in Keys]:any
} //-> {a:any,b:any,c:any}
- T[K]: 索引访问
interface IPerson{
name:string;
age:number;
}
let type1:IPerson['name']//string
let type2:IPerson['age']//number
- extends:泛型约束
interface Length{
length:number
}
function Log<T extends Length>(arg:T):T{
console.log(arg.length);
return arg;
}
Log({value:3})//提醒出现错误
Log({length:3})
常用工具类型
-
Partial:将类型属性变为可选
-
Required:将类型属性变为必选
-
Readonly:将类型属性变为只读
-
Pick、Record...
TS实战
声明文件
-
declare:三方库需要类型声明文件
-
.d.ts:声明文件定义
-
@types:三方库TS类型包
-
tsconfig.json:定义TS的配置
总结
现在只是学习到了TS的皮毛部分,不过对其有了大概的理解,简而言之就是对js的弱类型进行限制,达到一个更好的代码规范和开发环境,总之首先要用起来 只有不断地基于实战练习最终才能掌握一门技术的精髓
最后还是推荐给大家几个我认为比较好的文章
type和interface的区别知多少? - 掘金 (juejin.cn)
2022年了,我才开始学 typescript ,晚吗?(7.5k字总结) - 掘金 (juejin.cn)