这里有很多类似的问题,但它们没有涵盖帖子末尾的清单(特别是“值未定义”部分)。
我有一个枚举
enum E {
A = 'A',
B = 'B'
}
Run Code Online (Sandbox Code Playgroud)
然后我想将我的对象值限制为状态,{ [key in E]: string }但这要求我实例化该对象已经是所有枚举的键。这是不允许的:
const state: { [key in E]: string } = {};
Run Code Online (Sandbox Code Playgroud)
类型“{}”缺少类型“{ A: string;”的以下属性 B:字符串;}':A、B
所以我尝试这样约束它{ [key in E]?: string }。这允许我省略枚举键,从而允许实例化空对象{}并检查键值是否在枚举范围内:
state.A = 'x'; // ok
state.C = 'y'; // gives error which is nice
Run Code Online (Sandbox Code Playgroud)
但后来我在 forEaching 对象条目时遇到了问题
Object.entries(state).forEach(([key, value]) => console.log(value === undefined));
Run Code Online (Sandbox Code Playgroud)
Typescript 认为这value可以是类型string|undefined,但事实并非如此。
仅使用字符串作为键时,该值不被视为未定义
const state: { [key: string]: string } = {};
Run Code Online (Sandbox Code Playgroud)
如何将对象键限制为枚举值,同时不需要它们的存在并且值不是未定义的?
清单:
state.A = 'x' // ok
state.C = 'x' // error
Object.entries(state).forEach(([key, value])=>console.log(value.charAt(0))); // ok, no Object is possibly 'undefined'.(2532) error
Run Code Online (Sandbox Code Playgroud)
TLDR:我想去掉assert示例中的
就打字稿而言,从对象中省略与显式设置A为 相同。这样做很好:Aundefined
const state: { [key in E]?: string } = {};
state.A = undefined;
Run Code Online (Sandbox Code Playgroud)
@captain-yossarian 为您提供了一种很好但非常复杂的方法来防止这种行为。更简单的方法是简单地过滤掉任何undefined值。
这个回调是一个类型保护,它确保元value组中的[key, value]被定义。
const isDefinedValue = <T,>(tuple: [string, T | undefined]): tuple is [string, Exclude<T, undefined>] => {
return tuple[1] !== undefined;
}
Run Code Online (Sandbox Code Playgroud)
然后我们可以Object.entries在使用之前过滤它。
Object.entries(state)
.filter(isDefinedValue)
.forEach(([key, value])=>console.log(value.charAt(0))); // value is `string`
Run Code Online (Sandbox Code Playgroud)