通用功能的对象

时间:2018-11-25 02:21:30

标签: typescript

我正在尝试使此打字稿正常工作,但是我无法弄清楚如何键入datia = dict(type = 'choropleth', locations = df['Names'], locationmode = 'USA-states', colorscale= 'Portland', text= df['Names'], z=df['2010-11'], colorbar = {'title':'Vaccine Coverage in percentage'}) layout = dict(title = 'Vaccine Coverage in percentage', geo = {'scope':'usa'}) choromap = go.Figure(data = [datia],layout = layout) iplot(choromap, validate=False) 对象以使openPromises函数不会因为键入错误而出错。我看到的错误是:

resolve

一个简单的解决方法是将Type '(value?: B | PromiseLike<B> | undefined) => void' is not assignable to type '<C>(value?: C | undefined) => void'. Types of parameters 'value' and 'value' are incompatible. Type 'C | undefined' is not assignable to type 'B | PromiseLike<B> | undefined'. Type 'C' is not assignable to type 'B | PromiseLike<B> | undefined'. Type 'C' is not assignable to type 'PromiseLike<B>'. 的值键入为openPromises,但是希望对此进行改进,并在此过程中进一步了解复杂的泛型类型。

这是我演示问题的代码。我的消息来源要复杂得多,但这是我所能创建的能证明问题的最低要求

any

您可以在this typescript code sandbox的左侧看到错误。感谢您的帮助!

1 个答案:

答案 0 :(得分:1)

问题是您尝试执行的操作实际上不是安全的。泛型函数是具有由调用者确定的类型参数的函数。在您的情况下,呼叫者只能传递有效的单一类型,即为特定ID调用putInObject时确定的类型。因此,例如,即使无效,这也是允许的:

putInObject<MyResponse1>("test1").then(r => console.log(r.AA)); // expecting r to be MyResponse1
openPromises["test1"].resolve({ a:'a', BB: "test" }) // I can pas in anything since resolve is generic

没有一种真正可靠的安全方式来预先输入openPromises。由于每个键只有一个有效的类型,并且以后会添加键,因此我们无法真正将openPromise的类型用作模拟此行为的

我可以想到两种解决方法。

更改原始对象的类型

Typescript不允许我们在声明变量后更改其类型,但是我们从putInObject(同一个对象但类型不同的对象)openPromisses返回,然后进行冷处理,然后使用此新对象代替。在下面,我使用了一个类来保留class OpenPromisesManager<T = {}> { readonly openPromises: T = {} as T; putInObject<B extends DefaultResponse>(){ return <TKey extends string>(id: TKey, withPromise: (p:Promise<B>) => void): OpenPromisesManager<T & Record<TKey, { resolve(value?: B): void }>> => { const newThis = this as any ; withPromise(new Promise<B>(resolve => { newThis.openPromises[id] = { resolve }; })); return newThis as OpenPromisesManager<T & Record<TKey, { resolve(value?: B): void }>>; } } } // ---------- interface MyResponse1 extends DefaultResponse { AA: string; } const mgr = new OpenPromisesManager() const mgr2 = mgr.putInObject<MyResponse1>()("test1", p=> p.then(r=> console.log(r.AA))); const response1: MyResponse1 = { a:'a', AA: "test" }; mgr2.openPromises["test1"].resolve(response1) mgr2.openPromises["test1"].resolve({ a:'a', BB: "test" }) // error

的当前类型
get

使用捕获请求类型的键

另一种选择是使键的类型保持承诺的预期收益类型。这使我们能够创建一个resolve函数,该函数将返回具有适当const openPromises: unknown = {}; type Key<T> = string & { __type: T } function key<T>(k: string) { return k as Key<T>; } function putInObject<B extends DefaultResponse>(id: Key<B>) { return new Promise<B>(resolve => { (openPromises as any)[id] = { resolve }; }) } function get<B>(id: Key<B>): { resolve(value?: B): void } { return (openPromises as any)[id]; } // ---------- interface MyResponse1 extends DefaultResponse { AA: string; } const test1 = key<MyResponse1>("test1"); putInObject<MyResponse1>(test1).then(console.log); const response1: MyResponse1 = { a:'a', AA: "test" }; get(test1).resolve(response1) get(test1).resolve({ a: 'a', BB: ''}) // error 类型的对象。

Pairwise(K,V);