Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在TypeScript中将字符串强制转换为枚举_Typescript_Intellisense_Ecmascript 2017 - Fatal编程技术网

在TypeScript中将字符串强制转换为枚举

在TypeScript中将字符串强制转换为枚举,typescript,intellisense,ecmascript-2017,Typescript,Intellisense,Ecmascript 2017,我在使用TypeScript中的枚举时遇到了一个小问题。我的设想是: 我定义了一个包含允许值的字符串枚举 我已经定义了一个方法,该方法接受任何传入值(类型为stringtype),并且必须将其强制转换为所述枚举 问题是,即使在检查从该方法传入的值之后,intellisense告诉我值仍然是字符串的类型,而不是枚举。如何强制value成为AllowedValues的一种类型 以下是一个概念验证示例: /** enum */ enum AllowedValues { LOREM_IPSU

我在使用TypeScript中的枚举时遇到了一个小问题。我的设想是:

  • 我定义了一个包含允许值的字符串枚举
  • 我已经定义了一个方法,该方法接受任何传入值(类型为
    string
    type),并且必须将其强制转换为所述枚举
问题是,即使在检查从该方法传入的
之后,intellisense告诉我
仍然是
字符串
的类型,而不是枚举。如何强制
value
成为
AllowedValues
的一种类型

以下是一个概念验证示例:

/** enum */
enum AllowedValues {
    LOREM_IPSUM = 'lorem ipsum',
    DOLOR_SIT = 'dolor sir',
    AMET = 'amet'
}

/** @method */
function doSomething(value: string = AllowedValues.LOREM_IPSUM) {

    // If value is not found in enum, force it to a default
    if (!(Object as any).values(AllowedValues).includes(value))
        value = AllowedValues.LOREM_IPSUM;

    // Value should be of type `AllowedValues` here
    // But TypeScript/Intellisense still thinks it is `string`
    console.log(value);
}

doSomething('amet');    // Should log `amet`
doSomething('aloha');   // Should log `lorem ipsum`, since it is not found in `AllowedValues`

你也可以在上面找到它。

这里有一些事情。一个是TypeScript不理解
Object.values(x).includes(y)
是一个on
y
。它与编译器试图缩小类型的内置方式不匹配,例如
typeof
instanceof
检查中的
。要帮助编译器完成此任务,可以使用a来表示这种检查方式:

function isPropertyValue<T>(object: T, possibleValue: any): possibleValue is T[keyof T] {
  return Object.values(object).includes(possibleValue);
}

declare function onlyAcceptAllowedValues(allowedValue: AllowedValues): void;
declare const v: string;
if (isPropertyValue(AllowedValues, v)) {
  onlyAcceptAllowedValues(v); // v is narrowed to AllowedValues; it works!
}
哦,还是不行


第二件事是:如果重新分配变量的值,TypeScript实际上放弃了它的收缩。编译器花了相当大的精力来理解控制流对变量类型的影响,但是。因此,即使我们理解将
AllowedValues.LOREM_IPSUM
赋值给
value
会使它成为
AllowedValues
,编译器也会假设它是其原始的注释类型,即
字符串

处理这个问题的方法是创建一个新的变量,编译器知道这个变量除了
AllowedValues
之外,永远不会是任何东西。最简单的方法是将其设置为
const
变量,如下所示:

function doSomething(value: string = AllowedValues.LOREM_IPSUM) {    
  const allowedValue = isPropertyValue(AllowedValues, value) ? value : AllowedValues.LOREM_IPSUM;
  console.log(allowedValue);
}
在上面,新变量
allowedValue
被推断为
AllowedValues
,因为如果类型保护成功(此时
value
是一个
AllowedValues
),或者如果类型保护失败,它被设置为
value
,或者
AllowedValues.LOREM_IPSUM
。无论哪种方式,
allowedValue
都是一个
allowedValue



因此,如果您想帮助编译器理解一些事情,那么这将是我建议的更改。希望有帮助。祝你好运

const av=Object.keys(AllowedValues).find(k=>AllowedValues[k]==='dolor sir')作为AllowedValues;控制台日志(av);谢谢你的详细回答!现在,这对我来说是有意义的:我不知道如果变量重新分配在任何时候发生,TypeSCript将默认为原始的带注释的类型。
function doSomething(value: string = AllowedValues.LOREM_IPSUM) {    
  const allowedValue = isPropertyValue(AllowedValues, value) ? value : AllowedValues.LOREM_IPSUM;
  console.log(allowedValue);
}