TypeScript 什么是“完全在类型系统内构建”的意思
问题描述
一段时间前,我看到有人在类型系统中完全实现了flappy bird,我看了代码,代码是用typescript写的,但我理解不多。
类型是用于明确指示类型的,而泛型使类型系统更具功能性,但仅限于此。据我所知,typescript中的类型系统无法执行实际代码,那么是如何做到的呢?
解决方案
Typescript的类型在运行时无法“执行实际代码”,但它们仍然可以表达关系和转换。实际上,它非常类似于函数式编程。
type Transform<T> = {
[K in keyof T]: {
value: T[K]
}
}
type A = { foo: string, bar: string }
type B = Transform<A>
// { foo: { value: string }, bar: { value: string } }
在这个愚蠢的例子中,
Transform
可以被看作是一个接受名为
T
的参数的“函数”,它“返回”另一种派生自
T
的类型。
这有点像在编译时运行的程序,而不是运行时。上面的Typescript代码编译成一个空文件,因为它不包含可执行的运行时代码。
因此,上述代码可以被描述为“完全在类型系统中”。
现在,如果它从不接触可执行代码,它还有用吗?可能没有。但这种类型的东西展示了Typescript用类型描述复杂行为的能力。
我见过的一个最好的例子就是ts-sql,它实现了一个包含SQL查询解析的SQL数据库。
import { Query } from "@codemix/ts-sql";
const db = {
things: [
{ id: 1, name: "a", active: true },
{ id: 2, name: "b", active: false },
{ id: 3, name: "c", active: true },
],
} as const;
type ActiveThings = Query<
"SELECT id, name AS nom FROM things WHERE active = true",
typeof db
>;
// ActiveThings is now equal to the following type:
type Expected = [{ id: 1; nom: "a" }, { id: 3; nom: "c" }];
你提供了一个数据库状态,它是一种类型。然后你使用字符串文字类型查询它,它返回更多类型。所以就像我上面的简单示例一样,你有类型传递给其他类型,以输出在输入类型上的逻辑派生类型。
所以再次说,这在真实应用中有用吗?可能不。但它确实很酷!