将通用对象分配给Partial类型

LppEdd

一段时间后,我再次使用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'

无法理解如何解决此问题,同时保持正确的输入。

卡兹

不幸的是,编译器无法为您验证这一点,在这种情况下,您对编译器了解更多,一种合理的解决方案是使用类型断言

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会将其扩展为并将结果对象视为带有字符串索引签名的对象,从而得出奇怪的结果:

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上面应该是type {a: number} | {z: number}使用泛型还不清楚。也许o3上面应该是类型Partial<Record<K, number>>无论如何,字符串索引签名都不是一件好事,它会破坏您所看到的东西。


另一个绊脚石是,即使编译器意识到计算出的属性可以根据泛型类型分配给某种合适的类型,T并且K也可能无法识别出该类型可以分配给Partial<T>对于人类来说,这很容易理解,但是编译器不一定会推理出这种类型的高阶类型操作。与此相关的规范性开放问题可能是microsoft / TypeScript#28884,其中的问题是,当为通用Pick<T, K> & Omit<T, K>它不被视为与兼容对于任何静态已知的type,编译器都可以进行分析:确实被视为可分配给TTKTKPick<{a: string, b: string}, "a"> & Omit<{a: string, b: string}, "a">{a: string, b: string}但是一旦使类型成为通用类型,编译器就会基本放弃。


由于这两个原因,让编译器为您验证可分配性的可能性很小。我能提供的最佳建议是使用该类型声明并继续。

好吧,希望能有所帮助;祝好运!

操场上的代码链接

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

将具体地图分配给通用类型的地图

来自分类Dev

打字稿-指定类型的对象无法分配给通用类型

来自分类Dev

将null分配给模拟的通用nullable数据类型时出现问题

来自分类Dev

无法将函数分配给具有通用参数的类型

来自分类Dev

将单位类型分配给变量

来自分类Dev

将Integer类型分配给int

来自分类Dev

将任何类型分配给变量

来自分类Dev

将功能分配给Javascript对象

来自分类Dev

将密钥分配给JSON对象

来自分类Dev

将字典分配给类对象

来自分类Dev

将数组分配给对象?

来自分类Dev

将数组分配给对象?

来自分类Dev

将Image对象分配给变量

来自分类Dev

将数组分配给对象

来自分类Dev

通用扩展参数不能分配给参数类型

来自分类Dev

将变量分配给相同类型的对象时,类型不匹配错误

来自分类Dev

将匿名对象分配给类型属性时,TypeScript是否会推断强制类型转换?

来自分类Dev

将类型分配给Maybe类型的嵌套类型的属性

来自分类Dev

将通用接口的实现分配给属性

来自分类Dev

将通用变量作为long分配给CountDownTimer

来自分类Dev

VBA:将通用OLEObject分配给CheckBox变量

来自分类Dev

如何将引用值分配给通用属性

来自分类Dev

类型对象不可分配给类型 any[]

来自分类Dev

将扩展类型的对象分配给基类型的对象时,我可以获得正确的类型吗

来自分类Dev

即使是强类型,也将值作为字符串分配给对象

来自分类Dev

这段代码如何将子类对象分配给超类类型?

来自分类Dev

无法将类型“ MyClass”的值分配给类型“ MFMailComposeViewControllerDelegate!”!

来自分类Dev

无法将类型“ [PHAsset]”的值分配给类型“ UIImageView!”

来自分类Dev

无法将类型“ AppDelegate”的值分配给类型“ CLLocationManagerDelegate?”

Related 相关文章

  1. 1

    将具体地图分配给通用类型的地图

  2. 2

    打字稿-指定类型的对象无法分配给通用类型

  3. 3

    将null分配给模拟的通用nullable数据类型时出现问题

  4. 4

    无法将函数分配给具有通用参数的类型

  5. 5

    将单位类型分配给变量

  6. 6

    将Integer类型分配给int

  7. 7

    将任何类型分配给变量

  8. 8

    将功能分配给Javascript对象

  9. 9

    将密钥分配给JSON对象

  10. 10

    将字典分配给类对象

  11. 11

    将数组分配给对象?

  12. 12

    将数组分配给对象?

  13. 13

    将Image对象分配给变量

  14. 14

    将数组分配给对象

  15. 15

    通用扩展参数不能分配给参数类型

  16. 16

    将变量分配给相同类型的对象时,类型不匹配错误

  17. 17

    将匿名对象分配给类型属性时,TypeScript是否会推断强制类型转换?

  18. 18

    将类型分配给Maybe类型的嵌套类型的属性

  19. 19

    将通用接口的实现分配给属性

  20. 20

    将通用变量作为long分配给CountDownTimer

  21. 21

    VBA:将通用OLEObject分配给CheckBox变量

  22. 22

    如何将引用值分配给通用属性

  23. 23

    类型对象不可分配给类型 any[]

  24. 24

    将扩展类型的对象分配给基类型的对象时,我可以获得正确的类型吗

  25. 25

    即使是强类型,也将值作为字符串分配给对象

  26. 26

    这段代码如何将子类对象分配给超类类型?

  27. 27

    无法将类型“ MyClass”的值分配给类型“ MFMailComposeViewControllerDelegate!”!

  28. 28

    无法将类型“ [PHAsset]”的值分配给类型“ UIImageView!”

  29. 29

    无法将类型“ AppDelegate”的值分配给类型“ CLLocationManagerDelegate?”

热门标签

归档