过一会儿,我再次使用TypeScript,但是我一直陷在这个问题上。
export class CrossBrowserStorage<T> {
getValue<P extends keyof T>(
key: P,
defaultValue: T[P]
): Observable<T[P]> {
return this.getValues({ [key]: defaultValue }).pipe(map(values => values[key]));
----^ TS2345: Argument of type '{ [x: string]: T[P]; }' is not assignable
to parameter of type 'Partial '
}
getValues(keys: Partial<T>): Observable<Partial<T>> {
return from(browser.storage.sync.get(keys) as Promise<Partial<T>>);
}
}
TS2345:类型
的参数'{ [x: string]: T[P]; }'
的参数不可分配给 类型'Partial'
在保持正确输入的情况下无法理解如何解决此问题。
答案 0 :(得分:1)
不幸的是,编译器将无法为您进行验证,在这种情况下,您对编译器有了更多的了解,一种合理的解决方案是使用type assertion:
class Class<T> {
f<K extends keyof T>(k: K, v: T[K]) {
const badPartial: Partial<T> = { [k]: v }; // error!
const goodPartial: Partial<T> = { [k]: v } as Pick<T, K> & Partial<T>; // okay
}
}
这就是您需要做的。但是为什么会这样呢?编译器似乎面临两个主要绊脚石。
第一个绊脚石是,如果键是单个静态已知的文字或唯一符号类型,则编译器仅知道如何解释计算的属性:
const k1 = "a";
const o1 = { [k1]: 123 };
// const o1: {[k1]: number};
o1.a; // okay
o1.b; // error
相反,如果键类型是泛型或字符串文字的并集,则编译器将其扩展为string
并将产生的对象与string index signature视为一个对象,结果很奇怪:< / p>
const k2 = Math.random() < 0.5 ? "a" : "z";
const o2 = { [k2]: 123 };
// const o2: {[x: string]:number};
o2.a; // no error, but might not exist
o2.b; // no error, but *definitely* doesn't exist
function foo<K extends string>(k3: K) {
const o3 = { [k3]: 123 };
// const o3: {[x: string]:number};
o3.a; // no error, but probably doesn't exist
}
这是TypeScript中的未解决问题;参见microsoft/TypeScript#13948。很明显,对于字面量的并集来说,要做的“正确的事情”是什么?大概上面的o2
应该是{a: number} | {z: number}
类型。使用泛型还不清楚。也许上面的o3
应该是Partial<Record<K, number>>
类型。在任何情况下,字符串索引签名都不好,并且会破坏您所看到的东西。
另一个绊脚石是,即使编译器意识到根据通用类型T
和K
可以将计算出的属性分配给某些合适的类型,它也可能无法识别出这种情况。类型可分配给Partial<T>
。对于人类来说,这很容易理解,但是编译器不一定会推理出这种类型的高阶类型操作。与此相关的规范性公开问题可能是microsoft/TypeScript#28884,其中的问题是,在Pick<T, K> & Omit<T, K>
或T
是通用的情况下,T
与K
不兼容。对于任何静态已知的类型T
和K
,编译器都可以进行分析:Pick<{a: string, b: string}, "a"> & Omit<{a: string, b: string}, "a">
实际上被视为可分配给{a: string, b: string}
。但是一旦将类型设为通用类型,编译器便会放弃。
由于这两个原因,几乎没有机会让编译器为您验证可分配性。我能提供的最佳建议是使用该类型声明并继续。
好的,希望能有所帮助;祝你好运!