gpt4 book ai didi

typescript - 自动检测两种返回类型之一

转载 作者:搜寻专家 更新时间:2023-10-30 21:48:24 24 4
gpt4 key购买 nike

我有一个名为 isDone() 的函数,它返回与两种数据结构之一相同的信息(例如,散列数组或散列字典):

public async isDone() {
this.startDelayedTasks();
await Promise.all(this._tasks);
const hadErrors = this._failed.length > 0 ? true : false;
if (hadErrors) {
throw new ParallelError(this);
}
return this._resultType === "hash"
? (this._results as IDictionary<T>)
: hashToArray<IParallelArrayType<T>>(this._results) as IParallelArrayType<T>[];
}

IParallelArrayType 在哪里:

export interface IParallelArrayType<T> {
name: string;
value: T;
}

对于要求数组类型的消费者,他们可能希望运行标准的纯数组函数,如 mapfilter,甚至只是 length 但因为返回类型只有可能 是数组,所以会出现以下错误:

enter image description here

当然,消费者可以通过执行以下操作来解决此问题:

if(Array.isArray(results)) {
expect(results.length).to.equal(4);
}

但如果有某种方法可以避免消费者的这种负担,那就太好了。我在想象类似标记联合类型的东西,并且可能使用 Symbol 作为属性?

看起来像这样的东西可能会让我到达那里,但要真正让它大放异彩,我希望散列/字典返回类型的消费者不要让 Symbol 键成为他们标准迭代工具的一部分 Object.keys (字典)。这是可能的还是我要接近运行时环境才能正常工作?

最佳答案

只是跟进作为答案。您提出的想法仍然需要消费者执行某种检查或断言,以说服编译器返回的值是数组而不是字典。

减轻消费者负担的唯一方法是确保在您调用 returnAsArray() 后流畅的接口(interface)类型改变到保证 isDone() 的类型版本返回一个数组。由于 TypeScript 不支持改变对象类型的想法,因此最好返回一个不同的对象。这是作为代码的想法的草图。它没有使用与您相同的类型或逻辑(同步和手动设置结果),但它应该给出如何实现它的图片:

type Dictionary<T> = { [k: string]: T }
type EntryArray<T> = { k: string, v: T }[];
type ResultType<T> = {
dict: Dictionary<T>;
array: EntryArray<T>;
}

这里有两种结果类型,以及来自字符串 "dict" 的映射。和 "array"到各自的类型。现在我们定义我们的流利类:

class FluentThing<T, R extends keyof ResultType<T>=keyof ResultType<T>> {
readonly resultType: R;
results: Dictionary<T> = {};
constructor() {
this.resultType = "dict" as R;
}
getResults(): ResultType<T>[R] {
if (this.resultType === "dict") {
return this.results;
} else {
return Object.keys(this.results).
map(k => ({ k: k, v: this.results[k] }));
}
}
addResult(k: string, v: T) {
this.results[k] = v;
return this;
}
someMethod() {
return this;
}
wantArray(): FluentThing<T, "array"> {
return Object.assign(
new FluentThing(), this, { resultType: "array" }
) as FluentThing<T, "array">;
};
wantDict(): FluentThing<T, "dict"> {
return Object.assign(
new FluentThing(), this, { resultType: "dict" }
) as FluentThing<T, "dict">;
}
}

请注意 resultType属性是字符串之一 "array""dict" , 它是 readonly并不意味着改变。当您调用 wantArray()wantDict() , 一个新的 FluentThing使用与当前对象相同的数据创建对象,但指定的 resultType 除外。属性(property)。还要注意 getResults() 如何方法返回 ResultType<T>[R] ,即 Dictionary<T>如果R"dict" , 或 EntryArray<T>如果R"array" .

让我们使用它:

const ft = new FluentThing<number>().addResult("a", 3).
addResult("b", 4).someMethod();
const dict = ft.wantDict().someMethod().getResults();
// dict known to be Dictionary<number> at compile time,
// {a: 3, b: 4} at runtime
const arr = ft.wantArray().someMethod().someMethod().getResults();
// arr known to be EntryArray<number> at compile time,
// [{k: "a", v: 3}, {k: "b", v: 4}] at runtime.

这一切都有效,消费者可以避免不必要的检查或断言。耶!


此时请注意返回新对象而不是改变现有对象的重要性。如果你确实改变了 resultType当前对象并返回 this什么时候wantArray()wantDict()被称为......你冒着消费者会做如下事情的风险:

const wantArray = ft.wantArray(); 
const wantDict = ft.wantDict();
const shouldBeArray = wantArray.getResults();

契约(Contract)FluentThing声明 shouldBeArray将是一个数组,但如果你只有一个 FluentThing反对并改变它的resultType每当wantXXX()被称为,它不会,因为wantDict()wantArray() 之后被调用.只有您知道您的消费者是否可能保留流畅界面的中间值并尝试重用它们。如果没有,那么尽管有这个问题,突变也许对你有用。


另请注意,我不确定为什么要让消费者在实际获取结果之前指定他们希望将结果作为数组或字典。如果这个决定被推迟到数据实际返回给消费者时,无论是从消费者的角度还是从类型系统的角度来看都会更直接:

type Dictionary<T> = { [k: string]: T }
type EntryArray<T> = { k: string, v: T }[];

class FluentThing<T> {
results: Dictionary<T> = {};
getResultsAsDictionary(): Dictionary<T> {
return this.results;
}
getResultsAsArray(): EntryArray<T> {
const resultsDict = this.getResultsAsDictionary();
return Object.keys(resultsDict).map(k => ({ k: k, v: resultsDict[k] }));
}
addResult(k: string, v: T) {
this.results[k] = v;
return this;
}
someMethod() {
return this;
}
}

const ft = new FluentThing<number>().addResult("a", 3).
addResult("b", 4).someMethod();
const dict = ft.someMethod().getResultsAsDictionary();
const arr = ft.someMethod().someMethod().getResultsAsArray();

这与以前的版本几乎相同,除了一切都更简单。类似的东西可能更可取,除非您的用例要求消费者出于某种我看不到的原因尽早指定所需的结果格式。

无论如何,希望对您有所帮助。祝你好运!

关于typescript - 自动检测两种返回类型之一,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50548160/

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