TypeScript类型级别实例代码分析
代码如下:
/** * Try assigning "World" to `type Hello`! */ type Hello = "..."; // Type-level unit tests! // If the next line type-checks, you solved this challenge! type test1 = Expect>;
多年来,TypeScript的类型系统已经从基本的类型注释发展成为一种大型复杂的编程语言。如果你曾经研究过一个开源库的代码,你可能会发现一些看起来很吓人、很陌生的类型,比如来自另一个星球的一些深奥的语言。库代码通常需要比我们习惯编写的代码更抽象;
这就是为什么它广泛使用高级TypeScript功能,如泛型、条件类型、映射类型甚至递归类型。我个人在研究TS Pattern时学习了这些概念,这是一个开源库,具有极其难以键入的特殊性。在本课程中,我希望分享我通过阅读过多的源代码和对类型系统进行数百小时的修改所学到的知识。
类型之所以很棒,有很多原因:
类型可以作为代码的文档,以便查询。
类型可以向开发人员提供代码提示。
类型能发现错误和拼写错误。
类型系统对您的代码了解得越多,它对你的帮助就越大!一旦你精通TypeScript,一切都变得可能。您将不再觉得类型系统限制了您编写所需抽象的能力。
想不想检查路由参数传递的是否正确?
走你:
// ✅ this is correct ????
navigate("user/:userId", { userId: "2" });
// ✅ Looks good! `dashboardId` is optional.
navigate("user/:userId/dashboard(/:dashboardId)", { userId: "2" });
// ❌ `userId` is missing. Add one to fix the error!
navigate("user/:userId/dashboard(/:dashboardId)", { dashboardId: "2" });
// ❌ `oops` isn't a parameter. Remove it to fix the error!
navigate("user/:userId/dashboard(/:dashboardId)", { userId: "2", oops: ":(" });
// ???? Scroll to see how this works!
// ???? Here are the kind of things you will soon be able to do!
type ParseUrlParams =
Url extends `${infer Path}(${infer OptionalPath})`
? ParseUrlParams & Partial>
: Url extends `${infer Start}/${infer Rest}`
? ParseUrlParams & ParseUrlParams
: Url extends `:${infer Param}`
? { [K in Param]: string }
: {};
// navigate to a different route
function navigate(
path: T,
params: ParseUrlParams
) {
// interpolate params
let url = Object.entries(params).reduce(
(path, [key, value]) => path.replace(`:${key}`, value),
path
);
// clean url
url = url.replace(/((|)|/?:[^/]+)/g, '')
// update url
history.pushState({}, '', url);
}