我想使用来自 的字符串文字typescript。我的界面:
interface Props {
size: 'small' | 'medium' | 'large';
count: number;
}
Run Code Online (Sandbox Code Playgroud)
然而我遇到了两个问题:
如果我的数据在对象中
const data = {
size: 'small',
count: 36,
};
Run Code Online (Sandbox Code Playgroud)
然后当尝试解构它时,<Component {...data}>我收到以下错误:
Type 'string' is not assignable to type '"small" | "medium" | "large"'
Run Code Online (Sandbox Code Playgroud)
我使用环境变量得到完全相同的错误:
size = process.env.SIZE; // while having SIZE = 'small'; in my .env file
Run Code Online (Sandbox Code Playgroud)
有人可以帮我提供如何修复这些问题的建议吗?高度赞赏。
前言:我会为联合定义一个类型别名,这样您就可以在多个地方使用它:
type Size = "small" | "medium" | "large";
Run Code Online (Sandbox Code Playgroud)
用这个名字...
回复 #1:问题是,尽管您已使用"small"的值data.size,但它可以被任何其他字符串覆盖。它的类型是string,而不是Size( "small" | "medium" | "large")。"small" | "medium" | "large"不过,您可以通过为对象定义类型并将其应用于常量来告诉 TypeScript 它是data:
// 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
};
Run Code Online (Sandbox Code Playgroud)
...或通过类型断言:
const data = {
size: "small" as Size,
// ^^^^^^^^
count: 36,
};
Run Code Online (Sandbox Code Playgroud)
或者,如果data永远不会改变,你可以as const这样说:
const data = {
size: "small",
count: 36,
} as const;
//^^^^^^^^
Run Code Online (Sandbox Code Playgroud)
关于#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}"`);
}
}
Run Code Online (Sandbox Code Playgroud)
然后:
const envSize = process.env.SIZE;
assertValidSize(envSize);
data.size = envSize;
Run Code Online (Sandbox Code Playgroud)
有几种方法可以实现这一点(使用类型保护函数而不是断言函数等),但这就是基本思想。
在您提出的评论中:
是否可以在不手动遍历案例的情况下为环境变量创建断言函数?就像从类型本身获取值并循环它们一样?
如果您从类型开始,则不会,但您可以从有效大小的常量数组开始,然后基于该常量数组派生类型和类型断言函数(和/或类型保护函数):
// 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;
Run Code Online (Sandbox Code Playgroud)
on告诉as constTypeScriptsizes它的内容不会改变,这让 TypeScript
| 归档时间: |
|
| 查看次数: |
1527 次 |
| 最近记录: |