typescript - Typescript 类型匹配对象,其 valueOf 最终返回一个字符串
问题描述
我过度设计了与 astring
或对象匹配的类型,该对象valueOf()
在递归评估时最终返回 a 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()
返回调用它的 Object 的原始值。字符串字面量(例如'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
以此类推,以此类推。
在您的第二个代码块中,您将valueOf()
方法更改为foo()
,它不作为全局Object
类型的方法存在,因此不能满足valueOf()
您原来StringableObject
创建的无限循环。
希望这可以帮助。
推荐阅读
- python - 如何使用函数找到单词在列表中的位置?
- python - AttributeError:张量没有属性 Child
- c# - 命令聚合失败:来自 mongot :: 的远程错误由 :: \"origin\" 引起,必须是日期、数字或 geoPoint(来自 \"compound.should[1].near\")
- python-3.x - 如何将列表中的所有元组组合到一个列表中?还将列表中的第一行与所有其他行进行比较
- r - R:如何转换数据框
- javascript - TypeScript - 如何将反应上下文与调度动作分开?
- javascript - 如何在 Google 电子表格的 HTML 代码中创建和 JS 变量?
- google-analytics - 使用 UTM 参数查找站点上的所有 URL
- c++ - c ++将文件读入对象向量,然后复制到向量指针
- java - 试图在两个边界键之间找到符号表的严格范围