我正在尝试使此打字稿正常工作,但是我无法弄清楚如何键入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的左侧看到错误。感谢您的帮助!
答案 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);