大家好,最近开始在学 TypeScript,除了官方文件以外,也偶尔会翻阅保哥的免费电子书 will 保哥 - TypeScript 新手指南 (TS 影片介绍)
TypeHero 这个网站也是个很棒的学习资源~ 如果想把 TypeScript 学扎实的人,千万不要错过它!!
Summary
这篇文章主要会围绕在 TypeHero 和记录我自己刷题的心得
会挑选两题适合新手的题目(新手是我 (〃∀〃)
TypeHero 是什么
TypeHero 是由一位 Netflix 的资深工程师所开发的开源专案。可以把它想成是 TypeScript 版的 Leecode,上面从简单到困难的 TypeScript 题目都有!例如以 TypeHero 的「TypeScript Foundations」12 道题目来说,它涵盖了从基础语法到进阶概念的一系列题目,帮助我们消化、应用各个知识点。像是「原始资料型别」、「型别别名」、「字串字面量型别」、「索引签名」、「typeof」等。此外只要有 Github 帐号,登入后即可开始刷题!
以下撷取自 六角学院 - TS每日任务
适合新手: Tracks > TypeScript Foundations 的 12 道基础题目适合泛型新手:Explore > Beginner 想多练习更多初阶泛型应用可以试试看 Beginner 里的 14 道初阶泛型题目适合写过 1 年经验的 TypeScript 开发者:Explore > Easy适合中阶开发者:Explore > MediumTypeHero 网址 https://typehero.dev/
GitHub 开源专案 https://github.com/typehero/typehero
题目一:Primitive Data Types
第一题就以「原始型别」作为开门见山,因为 TypeScript 的基础概念之一就是能够创建原始类型
题目简述:需要在代码中添加原始类型,直到错误消失为止。解题中你可能会需要为物件添加上消失的属性
题目
const playSong = (artistName, year) => { return `${artistName} was released in the year ${year}`;};const artistName = 'Frank Zappa';const age = 52;interface Musician { artistName: string; // add the rest}const musicianInfo = ({ artistName, age, deceased }) => { return `${artistName}, age ${age}${deceased ? ' (deceased)' : ''}`;};musicianInfo({ artistName, age, deceased: true,});
答案
// playSong 函式带入了两个参数 artistName 以及 year,从以下的变数宣告可以知道型别分别是 string 和 numberconst playSong = (artistName: string, year: number) => {return `${artistName} was released in the year ${year}`;};// 这两个变数在 TypeHero 编辑器里没有出现红色蚯蚓警告有错,所以一开始忘记定义,送出就报错了const artistName: string = "Frank Zappa"; const age: number = 52;// 介面的名称:开头要大小写,代表一个型别interface Musician {artistName: string;age: number;// 这里官方有提示,下面也可以看到其实 musicianInfo 函式会带入三个参数,唯独少了 deceased // 在 interface 中物件必须跟介面的定义一致,多出或少了介面中的属性都不行deceased: boolean;}// musicianInfo 接受一个物件作为参数,这个参数必须符合 Musician 的介面结构const musicianInfo = ({ artistName, age, deceased }: Musician) => {return `${artistName}, age ${age}${deceased ? " (deceased)" : ""}`;};musicianInfo({artistName,age,deceased: true,});
补充
物件型别(Object type)
- 物件
- function
- array
- Date
- RegExp
- Error
小总结
针对这道题目和这段代码做个简单的总结
const musicianInfo = ({ artistName, age, deceased }: Musician) => {...}
结构赋值:在 musicianInfo 函式的参数中,{ artistName, age, deceased }
进行了结构赋值。当一个符合 Musician 介面结构的物件被传递给 musicianInfo 函式时,这个物件的 artistName、age 和 deceased 属性会被提取出来型别注释:Musician 这部分是对参数的型别注释。它告诉 TypeScript 编译器传给 musicianInfo 函式的物件必须符合 Musician 介面的结构在 TypeScript 中,原始型别会以小写字母定义除了原始型别外,TypeScript 还有一些较为进阶的类型,如 symbol、bigint、object、never、unknown 和 any题目二:Type Aliases
题目二是要使用型别别名(type aliases)来去定义型别
题目简述:创建必要的型别别名,如 Name、Year、Payload(甚至是别的),请仔细阅读测试
题目
// We completed the first alias (`Name`) for you to see as an exampletype Name = string;// Now try replacing `unknown` with a primitive data type that might be appropriate for `Year`type Year = unknown;type IsOperational = unknown;type Payload = { name: Name; // the tests show that you need a `mass` property here // but first you might need to create an alias for `Kilograms` // because that's the value of `mass`};
答案
// We completed the first alias (`Name`) for you to see as an exampletype Name = string;type Year = number; // 型别从底下测试可得知type Count = number; // 从底下测试的 Spacecraft 介面 里会知道 Count 用于计数,所以型别应是数字type IsOperational = boolean; // 型别从底下测试可得知// create an alias for `Kilograms`type Kilograms = number; type Payload = { name: Name; mass: Kilograms; // the tests show that you need a `mass` property here // but first you might need to create an alias for `Kilograms` // because that's the value of `mass`};
这题需仔细阅读下方的测试code,因为大部分的型别都可以从底下测试得知,包含 Payload 里有 mass 属性也是
小总结
建立型别别名就是使用「type」这个关键字type 后发定义的命名并没有强制规定一定要大写开头,但一般还是以大写开头,以提高code的可读性和易读性型别别名允许为任何型别定义一个新名称。不仅仅是简单的重新命名,还可以建立更複杂的型别结构,尤其是複杂的物件或联合型别不要过度使用,像是可以直接使用 Row[],就不应该创建 Rows 这样的别名如果文章内有任何错误或是描述不清的地方,欢迎留言让我知道
参考来源
TypeHero 大挑战
TypeHero