typescript - 类型字符串不可分配给字符串文字
问题描述
我想使用来自typescript
. 我的界面:
interface Props {
size: 'small' | 'medium' | 'large';
count: number;
}
但是我遇到了两个问题:
- 使用破坏时出错
如果我在对象中有我的数据
const data = {
size: 'small',
count: 36,
};
然后当试图解构它时,<Component {...data}>
我得到以下错误:
Type 'string' is not assignable to type '"small" | "medium" | "large"'
- 使用环境变量
我使用环境变量得到完全相同的错误:
size = process.env.SIZE; // while having SIZE = 'small'; in my .env file
有人可以帮助我就如何修复这些问题提供建议吗?高度赞赏。
解决方案
前言:我会为联合定义一个类型别名,所以你可以在多个地方使用它:
type Size = "small" | "medium" | "large";
用那个名字...
回复 #1:问题在于,尽管您已用作"small"
的值data.size
,但它可以被任何其他字符串覆盖。它的类型是string
,而不是Size
( "small" | "medium" | "large"
)。"small" | "medium" | "large"
但是,您可以通过为对象定义类型并将其应用于data
常量来告诉 TypeScript 它是:
// Inline, or use `type` to define it separately
const data: Props = {
// ^^^^^
size: 'small',
count: 36, // I've assumed the `number: 36` in the question is a typo
};
...或通过类型断言:
const data = {
size: "small" as Size,
// ^^^^^^^^
count: 36,
};
或者,如果data
永远不会改变,你可以as const
这样说:
const data = {
size: "small",
count: 36,
} as const;
//^^^^^^^^
关于#2,环境变量可以是任何东西,所以通常你会使用类型断言函数:
function assertValidSize(size: string): size is Size {
switch (size) {
case "small":
case "medium":
case "large":
return;
default:
throw new Error(`Invalid 'Size' value "${size}"`);
}
}
然后:
const envSize = process.env.SIZE;
assertValidSize(envSize);
data.size = envSize;
有几种方法可以旋转它(类型保护函数而不是断言函数等),但这是基本思想。
在您问过的评论中:
是否可以在不手动查看案例的情况下为环境变量创建断言功能?就像从类型本身中获取值并循环遍历它们?
如果您从类型开始,则不是,而是可以从有效大小的常量数组开始,然后基于该常量数组派生类型和类型断言函数(和/或类型保护函数):
// The valid sizes
const sizes = ["small", "medium", "large"] as const;
// The type for an entry in `sizes`
type Size = typeof sizes[number]; // Ends up being `"small" | "medium" | "large"
// A type assertion function for a valid size
function assertValidSize(size: string): asserts size is Size {
if (!(sizes as [string, string, string]).includes(size)) {
throw new Error(`Invalid Size value "${size}"`);
}
}
// Using it with `process.env.SIZE`:
assertValidSize(process.env.SIZE);
let size: Size = process.env.SIZE;
as const
on告诉 TypeScript 它的sizes
内容不会改变,这让 TypeScript
推荐阅读
- javascript - Angular Service 在延迟加载的模块中调用了两次
- google-app-engine - 如何部署需要定期访问大型数据文件的 Web 应用程序
- javascript - javascript画布。在全局组合操作之间切换
- javascript - JSON - 无法访问值
- javascript - 当提供一周中连续几天的字符串时,返回连接的星期几
- laravel - 我如何将 laravel echo 与 sanctum 和 socket.io 以及 nuxtjs 一起使用?
- concourse - 如何在 Concourse 作业中连接命令?
- javascript - 按钮单击音频启动和停止 JS
- python - Python - ModuleNotFoundError:没有命名的模块
- javascript - 为什么 for-in 循环不能有多个变量声明?