gpt4 book ai didi

typescript - 检查构建器模式中的详尽性

转载 作者:行者123 更新时间:2023-12-05 04:30:10 25 4
gpt4 key购买 nike

我想构建这样的东西:

type MyValues = "good" | "bad" | "ugly"

function doSomething(values:MyValues) {
return startBuilder(values)
.case("good", 1)
.case("bad", 2)
.exhaustive() // this should give an compiler error, since I forgot the `ugly` }

我尝试使用 TypeScript 的 infer 找出 tail - 但没有成功:

type Extract<T, A> = A extends T
? T extends infer Tail
? Tail
: never
: never;
type X = Extract<Values, 'good'>;

但这行不通。有什么想法吗?

这是一个 Playground :https://stackblitz.com/edit/typescript-mguypt

最佳答案

我们首先需要一个类型来检查两个类型是否完全相等,一个简单的 extends不会在这里做伎俩:

type Equals<A, B> = (<T>() => T extends A ? true : false) extends (<T>() => T extends B ? true : false) ? true : false;

可以在 here 中找到为什么这种看起来很有趣的类型有效的解释。由 jcalz 提供。

然后我们定义Builder类:

class Builder<T, SoFar extends ReadonlyArray<unknown> = []> {
private cases = new Map<T, unknown>();
}

它需要一个通用的 T这是它将检查其案例的内容,并且是不打算由最终用户传递的通用名称。这个通用 SoFar存储到目前为止使用了哪些案例。

那么让我们构建 case现在运行:

    case<V extends T>(v: V, d: unknown): Builder<T, [...SoFar, V]> {
this.cases.set(v, d);

return this as Builder<T, [...SoFar, V]>;
}

它需要扩展 T 的东西和任何值,然后将生成器返回为 Builder<T, [...SoFar, V]> ,这意味着我们将案例添加到目前用完的案例中。

终于到了:

    exhaustive(...args: Equals<T, SoFar[number]> extends true ? [] : [{ error: "Builder is not exhaustive." }]) {

}

我们检查是否TSoFar[number]是完全一样的。如果是,那么我们已经用尽了所有情况。否则,我们说我们期待一个参数。

因为您可能会调用 exhaustive没有参数,调用它而不用完所有情况将为用户显示一条很好的错误消息。

您甚至可以更进一步,在错误消息中包含所有缺失的案例!第二个 Playground 链接演示了这一点。

Playground

Playground with error messages that display missing cases

关于typescript - 检查构建器模式中的详尽性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72117512/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com