[英]Typescript error:Type 'number' is not assignable to type 'never'
interface Opts {
onFrame: () => void;
onAudioSample: null;
emulateSound: boolean;
sampleRate: number;
}
class NES {
constructor(opts: Opts) {
this.opts = {
onFrame() { },
onAudioSample: null,
emulateSound: true,
sampleRate: 44100,
}
if (typeof opts !== "undefined") {
let key: keyof Opts
for (key in this.opts) {
if (typeof opts[key] !== "undefined") {
// got err here
this.opts[key] = opts[key];
}
}
}
}
opts: Opts
}
you can cheak the error on TS playground: here你可以在 TS playground 上查错: 这里
typescript: v3.8.3 err: Type 'number'
is not assignable to type never
. typescript:v3.8.3
err: Type 'number'
不可分配给类型never
。 I don't understand why it is a never
type.我不明白为什么它是
never
类型。
You are getting that error because TypeScript can't infer that this.opts[key]
and opts[key]
are the same type.您收到该错误是因为 TypeScript 无法推断
this.opts[key]
和opts[key]
是同一类型。 If you were to cover up each half of the =
:如果你要掩盖
=
的每一半:
opts[key]
could be a Function
, null
, boolean
, or number
opts[key]
可以是Function
、 null
、 boolean
或number
this.opts[key]
needs to receive a Function
, null
, boolean
, or number
depending on the value of key
, which we don't know this.opts[key]
需要接收一个Function
, null
, boolean
或number
,具体取决于key
的值,我们不知道Function
, null
, boolean
, and number
is never
, so that's the type that TypeScript wants for this.opts[key]
Function
, null
, boolean
, and number
is never
, so that's the type that TypeScript wants for this.opts[key]
Interestingly, if you were to extract this to an anonymous generic function, it works: Within a single assignment Typescript can infer and use the type Opts[K]
.有趣的是,如果您要将其提取为匿名通用 function,它可以工作:在单个分配中 Typescript可以推断和使用类型 Opts
Opts[K]
。 jcalz suggests a similar solution in this similar question . jcalz在这个类似的问题中提出了类似的解决方案。
if (typeof opts[key] !== "undefined") {
// this.opts[key] = opts[key];
(<K extends keyof Opts>(k: K) => { this.opts[k] = opts[k]; })(key);
}
typescript playground typescript游乐场
That said, I would use the spread operator as in Mukesh Soni's answer , ending your assignment of this.opts
with ...opts
, or use Object.assign
.也就是说,我会像Mukesh Soni 的回答那样使用扩展运算符,用
...opts
结束你对this.opts
的分配,或者使用Object.assign
。 There's a slight risk that the passed opts
contains extra keys, but Typescript should ensure otherwise at compile time.传递的选项包含额外密钥的风险很小,但
opts
应在编译时确保否则。 (For that matter, if you're expecting opts
to be optional and potentially incomplete, it should probably be defined as opts?: Partial<Opts>
.) (就此而言,如果您希望
opts
是可选的并且可能不完整,那么它可能应该被定义为opts?: Partial<Opts>
。)
class NES {
constructor(opts?: Partial<Opts>) {
this.opts = Object.assign({
onFrame() { },
onAudioSample: null,
emulateSound: true,
sampleRate: 44100,
}, opts);
}
opts: Opts
}
See also: Object spread vs. Object.assign , which notes that the solutions are quite similar and both applicable for default options values.另请参阅: Object spread vs. Object.assign ,其中指出解决方案非常相似并且都适用于默认选项值。
I don't know why you are getting that error.我不知道你为什么会收到这个错误。 One other way to merge both the options might be to use spread operators.
合并这两个选项的另一种方法可能是使用扩展运算符。
this.opts = {
onFrame() { },
onAudioSample: null,
emulateSound: true,
sampleRate: 44100,
...opts
};
If you put the as any
after the property access, TypeScript will check that key
is a valid key如果您在属性访问后放置
as any
,TypeScript 将检查该key
是否为有效密钥
if (typeof opts[key] !== "undefined") {
(this.opts[key] as any) = opts[key];
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.