打字稿:文字类型的用户定义类型保护?

SumNeuron

注意:我是打字稿新手。在发布之前,我阅读了有关高级类型和类型保护文档另外,我还阅读了几个相关的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] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章