需要定义对象的任何一个属性的打字稿类型:如何?
Typescript type requiring any one attribute of an object to be defined: how?
我有以下 TypeScript 代码:
interface qux {
foo?: string;
bar?: number | string;
}
function foobar(x: qux) { ...; something_frobz(x); ...; }
问题:我可以调用 foobar("hello, world")
,即使这会导致 something_frobz
出现异常。我想在编译时使用字符串参数捕获并拒绝对 foobar
的调用,同时尽可能少地改变 qux 的结构。解决此问题的最佳方法是什么?
我自己的解决方案是将一个字段设为必填;该字段具有合理的默认值,并且 AFAIK 字符串没有任何具有相同名称的字段。这有点 hack,但它有效。
另一种方法可能是让 foobar 采用 first-field-is-required | second-field-is-required | ... | hundredth-field-is-required
的联合类型,但是我必须维护 qux 的 N 个几乎相同的副本(对于 N > 1)并且这永远不会顺利。
还有更好的吗?
打字稿版本 2.2 - 2.3
为了防止将 "primitives" 作为参数传递,您可以要求它是 object
:
function foobar(x: qux & object) { }
foobar(''); //error
foobar(1); //error
foobar({a:1}); //error
foobar({foo:'bar'}); //ok
Typescript 版本 >= 2.4 object
不再需要约束。有关详细信息,请参阅@dbandstra 的回答。
我想补充一点,Typescript 2.4 解决了这个问题。
TypeScript 2.4 introduces the concept of “weak types”. A weak type is any type that contains nothing but all-optional properties. [...] In TypeScript 2.4, it’s now an error to assign anything to a weak type when there’s no overlap in properties. That includes primitives like number
, string
, and boolean
.
我有以下 TypeScript 代码:
interface qux {
foo?: string;
bar?: number | string;
}
function foobar(x: qux) { ...; something_frobz(x); ...; }
问题:我可以调用 foobar("hello, world")
,即使这会导致 something_frobz
出现异常。我想在编译时使用字符串参数捕获并拒绝对 foobar
的调用,同时尽可能少地改变 qux 的结构。解决此问题的最佳方法是什么?
我自己的解决方案是将一个字段设为必填;该字段具有合理的默认值,并且 AFAIK 字符串没有任何具有相同名称的字段。这有点 hack,但它有效。
另一种方法可能是让 foobar 采用 first-field-is-required | second-field-is-required | ... | hundredth-field-is-required
的联合类型,但是我必须维护 qux 的 N 个几乎相同的副本(对于 N > 1)并且这永远不会顺利。
还有更好的吗?
打字稿版本 2.2 - 2.3
为了防止将 "primitives" 作为参数传递,您可以要求它是 object
:
function foobar(x: qux & object) { }
foobar(''); //error
foobar(1); //error
foobar({a:1}); //error
foobar({foo:'bar'}); //ok
Typescript 版本 >= 2.4 object
不再需要约束。有关详细信息,请参阅@dbandstra 的回答。
我想补充一点,Typescript 2.4 解决了这个问题。
TypeScript 2.4 introduces the concept of “weak types”. A weak type is any type that contains nothing but all-optional properties. [...] In TypeScript 2.4, it’s now an error to assign anything to a weak type when there’s no overlap in properties. That includes primitives like
number
,string
, andboolean
.