注意:我是打字稿新手。在发布之前,我阅读了有关高级类型和类型保护的文档。另外,我还阅读了几个相关的SO问题(例如,用户定义的类型防护[typescript]和如何为“字符串” |“文字” |“类型”编写用户定义的类型防护?)
与我的问题最相似的是后面的问题,您可能在文字上有一些自定义类型(在这种情况下string
,但解决方案也应适用number
),例如
type Format = 'JSON' | 'CSV' | 'XML'
在第二个问题中,用户询问有关打字稿keyof
关键词的解决方案,@ Ryan Cavanaugh的答案是通过将类型从a更改literal
为aninterface
并检查界面的键来解决的:
// copy-pasted from answer for convenience
interface McuParams {
foo, bar, baz;
}
function isKeyOfMcuParams(x: string): x is keyof McuParams {
switch (x) {
case 'foo':
case 'bar':
case 'baz':
return true;
default:
return false;
}
}
我的问题特别是是否存在使用类型本身进行用户定义类型防护的方法,例如
const isFormat = (maybe:String|Format): maybe is Format => /* something goes here */
据我所知,以下内容不起作用(仅替换/* something goes here */
):
// 1
/*
* As stated in the docs "The right side of the instanceof needs to
* be a constructor function" but we have a literal
*/
maybe instaceof Format
//2
/* As stated in the docs "typename" must be "number",
* "string", "boolean", or "symbol"
*/
typeof maybe === 'format'
//3
/* no idea */
(<Format>maybe)
那么@Ryan Cavanaugh的答案是唯一可行的解决方案吗?似乎非常冗长...
最好的方法是从像包含所有文字的数组之类 Format
的值派生类型Format
。有很多方法可以做到这一点。假设您使用的是TS3.4 +,我将展示最简单的方法:
const formats = ['JSON', 'CSV', 'XML'] as const;
type Format = typeof formats[number];
您可以验证Format
与以前相同。现在,有了一个数组,您可以使用它来构建类型保护:
function isFormat(x: string): x is Format {
// widen formats to string[] so indexOf(x) works
return (formats as readonly string[]).indexOf(x) >= 0;
}
这应该能按预期工作,并且不会太冗长(或者至少它不会在任何地方重复字符串文字)。希望能有所帮助;祝好运!
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句