不久前,我在推特上看到了一个完全在类型系统中实现Flappy Bird的人,我看了代码,它是Typescript 的,但我不能理解太多.
类型用于添加类型是什么的显式指示,泛型使类型系统功能更强大,但就我所知,TypeScrip中的类型系统不能执行实际代码,那么这是如何实现的?
不久前,我在推特上看到了一个完全在类型系统中实现Flappy Bird的人,我看了代码,它是Typescript 的,但我不能理解太多.
类型用于添加类型是什么的显式指示,泛型使类型系统功能更强大,但就我所知,TypeScrip中的类型系统不能执行实际代码,那么这是如何实现的?
类型脚本类型不能在运行时"执行实际代码",但它们仍然可以表达关系和转换.它实际上很像函数式编程.
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
派生的另一个类型.
这有点像是以compile time的速度运行的程序,而不是运行时.上面的类型脚本代码编译为一个空文件,因为它不包含可执行的运行时代码.
因此,上面的代码可以被描述为"完全在类型系统内".
现在,如果它从未触及可执行代码,那么这是useful吗?大概不会吧.但这类东西是一个展示TypeScrip用类型描述复杂行为的能力的窗口.
我见过的最好的例子之一是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" }];
您提供一个数据库状态,它是一种类型.然后使用字符串文字类型对其进行查询,这将返回更多类型.因此,就像我上面的简单示例一样,您可以将类型传递给其他类型,以输出更多的类型,这些类型是输入类型的逻辑派生.
那么,这在真正的应用程序中有用吗?大概不会吧.不过,这真的很酷!