我正在过度设计与string
或对象匹配的类型,该对象valueOf()
在进行递归求值时最终返回string
。
type Stringable = string | StringableObject;
interface StringableObject {
valueOf(): Stringable;
}
let x: Stringable;
// should work:
x = 'foo';
x = {
valueOf() { return 'foo'; }
};
x = {
valueOf() {
return {
valueOf() { return 'foo'; }
};
}
};
// should not work but do:
x = {}; // valueOf() returns an object -- a reference to x, itself
x = {
valueOf() { return 1; } // valueOf() returns a number
};
Object.prototype.valueOf()
,如果不被覆盖,则返回object
,而不是string
,所以我很困惑为什么最后的情况会编译,而我需要更改使其不被编译。
我怀疑我需要创建一个使用infer
关键字的泛型类型,但我仍在尝试如何infer
正确使用它。
奇怪的是,如果我更改valueOf
为foo
,它会达到我的期望。
type Stringable = string | StringableObject;
interface StringableObject {
foo(): Stringable;
}
// do not compile
x = {};
x = {
foo() { return 1; }
};
x = {
foo() {
return {
foo() { return 1; }
};
}
};
我认为它必须与valueOf()
本身的性质有关,或者与valueOf()
位于原型上而不是作为对象本身的定义有关的事实有关。但是,我不知道为什么会这样。
这里有一些误解,所以我将尝试分别解决每个误解,我希望这将有助于解释为什么您的代码无法产生预期的结果。
Object.prototype.valueOf()
,当不被覆盖时,它返回一个对象,而不是字符串,所以我很困惑为什么最后一种情况会编译,而我需要更改使其不被编译。
valueOf()
返回调用它的对象的原始值。'foo'
JavaScript将字符串文字(例如)视为原语,但是由于原语没有属性,因此JavaScript将原语强制转换为对象(实际上,它将尽可能强制转换任何类型以使操作有效)以允许基本类型为无效类型的操作。请查看此StackOverflow帖子,以获取有关对象强制的更多信息。这对您而言意味着的是,valueOf()
不一定会返回一个Object,而是会调用任何类型的原始值:
> "foo".valueOf()
'foo'
> let x;
> x = {}; x.valueOf()
{}
> x = 10; x.valueOf()
10
我正在过度设计一个与字符串匹配的类型,或者对一个对象进行递归求值时其valueOf()最终返回一个字符串。
该StringableObject
接口没有描述的类型,其valueOf()
方法最终会返回一个字符串。它确实描述了一个类型,该valueOf()
方法的方法将返回带有valueOf()
方法的类型,将返回带有valueOf()
方法的类型,诸如此类,这就是您的第一个代码块中的这一行所发生的一切:
x = {};
x
被分配给Object文字,该文字可以被强制转换成Object
其valueOf()
原语,该方法的方法返回一个新的原语,该原语也具有一种valueOf()
方法,该方法可以产生一个可以被强制转换为an Object
infinitum的原语。
在第二个代码块中,将valueOf()
方法更改为foo()
,它不作为全局Object
类型的方法存在,因此不能满足valueOf()
原始方法StringableObject
创建的无限循环。
希望这可以帮助。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句