【Typescript入门手册】一篇文章速览常见类型,2024年最新程序员应该学什么

先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7

深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Web前端全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上前端开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以添加V获取:vip1024c (备注前端)
img

正文

4.3 any在数组中的应用

一个比较常见的做法是,用 any 表示数组中允许出现任意类型:

let list: any[] = [‘xcatliu’, 25, { website: ‘http://xcatliu.com’ }];

对于any约束的数字,其实就是主动放弃了类型检测~

五、对象


除了原始类型,最常见的类型就是对象类型了。定义一个对象类型,我们只需要简单的列出它的属性和对应的类型。

5.1 对象属性注释

来看下面一段代码:

**注意:**此时参数的数量不一致,会导致报错,其实这是因为它们的形状不同,之后我们会展开来说~

function getName(obj: { name: string; age: number }): void {

console.log(obj.name);

console.log(obj.age);

}

const res = getName({ name: “余光”, age: 100 });

// ✅

const res2 = getName({ name: “余光”, age: 100 });

// ❌ 类型 “{ name: string; }” 中缺少属性 “age”,但类型 “{ name: string; age: number; }” 中需要该属性。

不难理解,我们将参数 obj 内部的属性进行了类型注释,并在之后检查对应的类型。

5.2 可选属性

对象类型可以指定一些甚至所有的属性为可选的,你只需要在属性名后添加一个 ?:

function getName(obj: { name: string; age?: number }): void {

console.log(obj.name);

console.log(obj.age);

}

getName({ name: “余光” });

注意可选属性可以不存在,但仍然不允许添加未定义的属性。

在JavaScript中,如果你获取一个不存在的属性,你会得到一个undefined而不是一个运行时错误。因此,当你获取一个可选属性时,你需要在使用它前,先检查一下是否是undefined

function getName(obj: { name: string; age?: number }): void {

console.log(obj.name);

console.log(obj.age);

}

getName({ name: “余光” });

// 余光

// undefined

六、函数


在函数是JavaScript中是一等公民,在Ts中,它允许我们指定输入类型和输出类型。

6.1 参数类型注解(Parameter Type Annotations)

当你声明一个函数的时候,你可以在每个参数后面添加一个类型注解,声明函数可以接受什么类型的参数。参数类型注解跟在参数名字后面:

函数声明:

function sum(x: number, y: number): number {

return x + y;

}

// 输入多余的(或者少于要求的)参数,是不被允许的:

sum(1);

// 应有 2 个参数,但获得 1 个。ts(2554)

sum(1, 2, 3);

// 应有 2 个参数,但获得 3 个

6.2 可选参数和参数默认值

前面提到,输入多余的(或者少于要求的)参数,是不允许的。那么如何定义可选的参数呢?与接口中的可选属性类似,我们用?表示可选的参数:

注意:可选参数必须接在必需参数后面。换句话说,可选参数后面不允许再出现必需参数了。

function hello(name1: string, name2?: string): void {

console.log(hello! ${name1} ${name2 ? "and" + " " + name2 : ""});

}

hello(“余光1”, “余光2”); // hello! 余光1 and 余光2

hello(“余光”); // hello! 余光

同样添加默认值也是可以的,TypeScript 会将添加了默认值的参数识别为可选参数:

function hello(name1: string = “余光”, name2: string = “yuguang”): void {

console.log(hello! ${name1} ${name2 ? "and" + " " + name2 : ""});

}

hello(); // hello! 余光 and yuguang

hello(“小明”); // hello! 小明 and yuguang

6.3 匿名函数

匿名函数有一点不同于函数声明,当 TypeScript 知道一个匿名函数将被怎样调用的时候,匿名函数的参数会被自动的指定类型。

这个例子来自“冴羽大佬”的示例👍

const arr = [1, 2, 3, 4];

arr.forEach((val) => {

val.toFixed(1);

});

// ✅

arr.forEach((val) => {

val.split(“-”);

});

// ❌ 类型“number”上不存在属性“split”。

尽管参数val并没有添加类型注解,但TypeScript根据forEach函数的类型,以及传入的数据的类型,最后推断出了val的类型。

这个过程被称为上下文推断(contextual typing),因为正是从函数出现的上下文中推断出了它应该有的类型。

七、联合类型(Union Types)


联合类型(Union Types)表示取值可以为多种类型中的一种。

7.1 定义一个联合类型

前面我们提到了基本类型是怎么指定的,如果你希望一个变量的类型是可选的可以使用any,但还有更好的方式——是明确指定几个类型——联合类型

let category: string | number;

category = ‘余光’;

category = 7;

category = true; // ❌ 不能将类型“boolean”分配给类型“string | number”。

联合类型使用 | 分隔每个类型。表示允许设置的类型,这其中每个类型都是联合类型的成员(members)。

注意

当TypeScript不确定一个联合类型的变量到底是哪个类型的时候,我们只能访问此联合类型的所有类型里共有的属性或方法:

function getLength(something: string | number[]): number {

return something.length;

}

// ✅

function getLength(something: string | number): number {

return something.length;

}

// ❌ 类型“string | number”上不存在属性“length”。类型“number”上不存在属性“length”。

联合类型的变量在被赋值的时候,会根据类型推论的规则推断出一个类型,所以也会遇到上面问题

let val: string | number;

val = ‘seven’;

console.log(val.length); // 5

val = 7;

console.log(val.length); // ❌ 类型“number”上不存在属性“length”

八、类型别名(type)


类型别名用来给一个类型起个“新”名字。例如:

type hasLen = string | number[]; // isNumber就是新名字,他可能更语义化一些

const arr: hasLen = [1];

又或者,常用语给一个联合类型定义自己的类型别名

type Name = string; // 字符串

type NameResolver = () => string; // 函数

type NameOrResolver = Name | NameResolver; // 联合类型

function getName(n: NameOrResolver): Name {

if (typeof n === “string”) {

return n;

} else {

return n();

}

}

九、接口(interface)


接口声明(interface declaration)是命名对象类型的另一种方式:

9.1 使用接口

来看下面一段代码:

function getName(obj: { name: string; age: number }): void {

console.log(obj.name);

console.log(obj.age);

}

const res = getName({ name: “余光”, age: 100 });

不难理解,我们将参数 obj 内部的属性进行了类型注释,并在之后检查对应的类型,再来看看使用了接口后的代码:

interface Person {

name: string;

age: number;

}

function getName(person: Person): void {

console.log(person.name);

console.log(person.age);

}

const person1 = { name: “余光1”, age: 100 };

const person2 = { name: “余光2”, age: 200 };

getName(person1); // 余光1 100

getName(person2); // 余光2 200

类似我们在上节使用的类型别名,这个例子也同样可以运行,就跟我们使用了一个匿名对象类型一样。TypeScript 只关心传递给 printCoord 的值的结构(structure)——关心值是否有期望的属性。

**注意:**类型别名和接口非常相似,大部分时候,你可以任意选择使用。接口的几乎所有特性都可以在 type 中使用,两者最关键的差别在于类型别名本身无法添加新的属性,而接口是可以扩展的。

十、类型断言(Type Assertion)


断言是编程术语,表示为一些布尔表达。—— 百度百科

类型断言(Type Assertion)可以用来手动指定一个值的类型。就是告诉编译器, 你不要帮我们检查了, 相信我,它就是这个类型。

在这里插入图片描述

断言就好比解释型强制类型转换,他会告诉你更加具体或者更不具体的类型!

值 as 类型;

有时候,我们确实需要在还不确定类型的时候就访问其中一个类型特有的属性或方法,就像这样:

interface fruits {

name: string;

getColor(): void;

}

interface person {

name: string;

getAge(): void;

}

type fruitsOrPerson = fruits | person;

function getColor(intance: fruitsOrPerson) {

return intance.getColor();

}

// 类型“fruitsOrPerson”上不存在属性“getColor”。

// 类型“person”上不存在属性“getColor”

上面的例子中,执行intance.getColor 的时候会报错。这是因为在它类型不确定时,我们使用了非共有属性或方法。

此时可以使用类型断言,将实例断言成fruits

interface fruits {

name: string;

getColor(): void;

}

interface person {

name: string;

getAge(): void;

}

type fruitsOrPerson = fruits | person;

function getColor(intance: fruitsOrPerson) {

return (intance as fruits).getColor(); // (method) fruits.getColor(): void

}

需要注意的是,类型断言只能够「欺骗」TypeScript 编译器,无法避免运行时的错误,不合理的使用会导致不可掌控的错误,例如:

interface fruits {

name: string;

getColor(): void;

}

interface person {

name: string;

getAge(): void;

}

type fruitsOrPerson = fruits | person;

// 通过

function getColor(intance: fruitsOrPerson) {

return (intance as fruits).getColor();

}

// 执行错误 intance.getColor is not a function

getColor({

name: “余光”,

getAge: () => {

return 100;

},

});

上面的例子编译时不会报错,但在运行时会报错:

紧跟潮流

大前端和全栈是以后前端的一个趋势,懂后端的前端,懂各端的前端更加具有竞争力,以后可以往这个方向靠拢。

这边整理了一个对标“阿里 50W”年薪企业高级前端工程师成长路线,由于图片太大仅展示一小部分

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip1024c (备注前端)
img

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
person;

// 通过

function getColor(intance: fruitsOrPerson) {

return (intance as fruits).getColor();

}

// 执行错误 intance.getColor is not a function

getColor({

name: “余光”,

getAge: () => {

return 100;

},

});

上面的例子编译时不会报错,但在运行时会报错:

紧跟潮流

大前端和全栈是以后前端的一个趋势,懂后端的前端,懂各端的前端更加具有竞争力,以后可以往这个方向靠拢。

这边整理了一个对标“阿里 50W”年薪企业高级前端工程师成长路线,由于图片太大仅展示一小部分

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip1024c (备注前端)
[外链图片转存中…(img-bFlBrGbm-1713214426397)]

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 7
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值