typescript - switch 语句中的打字稿类型生成问题
问题描述
我有这个渲染对象类型的映射函数。
function mapStuffs(fields: any) {
switch (fields.type) {
case "NewStuffs":
return {
type: "NewStuffs" as const,
stuff: fields.stuff
};
case "StuffFile":
const fileName = "jadflkjs";
const stuffId = "adlkajsf";
return {
type: "StuffFile" as const,
fileName,
stuffId
};
default:
return {
type: "ExistingStuff" as const
};
}
}
当我构建时,生成的类型是:
mainstuff:
| {
stuff: string | undefined;
type: "NewStuffs";
fileName?: undefined;
stuffId?: undefined;
}
| {
type: "StuffFile";
fileName: string;
stuffId: string;
}
| {
type: "ExistingStuff";
fileName?: undefined;
stuffId?: undefined;
};
我不明白如何在不需要时将fileName和stuffId作为可选参数删除。它是打字稿错误吗?我想要的是这种类型:
mainstuff:
| {
stuff: string | undefined;
type: "NewStuffs";
}
| {
type: "StuffFile";
fileName: string;
stuffId: string;
}
| {
type: "ExistingStuff";
};
解决方案
这不是 TypeScript 错误。这是预期的行为,因为 TypeScript 2.7为对象文字引入了改进的类型推断。fileName
某些返回值没有包含and的事实stuffId
使编译器认为缺少应该反映在返回类型中。
TypeScript 中的类型推断算法是一组启发式算法,语言设计者试图猜测在某些情况下大多数人希望看到什么样的东西。如果你不喜欢推断的类型,你可以自由地用你喜欢的任何类型来注释你的mapStuffs()
函数的返回类型,并且编译器会对此感到满意,假设你的函数实现符合它:
type MappedStuff = {
stuff: string | undefined;
type: "NewStuffs";
} | {
type: "StuffFile";
fileName: string;
stuffId: string;
} | {
type: "ExistingStuff";
};
function mapStuffs(fields: any): MappedStuff {
switch (fields.type) {
case "NewStuffs":
return {
type: "NewStuffs" as const,
stuff: fields.stuff
};
case "StuffFile":
const fileName = "jadflkjs";
const stuffId = "adlkajsf";
return {
type: "StuffFile" as const,
fileName,
stuffId
};
default:
return {
type: "ExistingStuff" as const
};
}
}
推荐阅读
- uml - 如何将用户模型配置文件导入 omnet++ 中的纸莎草项目?
- apache-kafka - Hyperledger Fabric - 通道尚未启动
- c# - 为什么我的 C# 项目文件没有源文件的 Compile Inlcude 元素
- html - 水平滚动时在一张桌子上工作的粘性标题
- rest - 微服务:API 调用与消息传递。何时使用?
- python - 使用第一个 lightgbm 的分数作为第二个 lightgbm 的初始分数给出不同的结果
- javascript - Webpack + SASS + Autoprefixer 不生成 CSS 文件
- c# - 如果按钮位于父面板中,则模板中单选按钮的双向绑定会出错
- html - 锚标签上的下载属性不适用于边缘中的相对路径
- dart - 我应该使用构造函数或方法来实现 Json 到 List