const str1: Path = "a.b" // good
const str2: Path = "a.b.c" // good
const str3: Path = "a..b" // false
const str1: Path = "a.b" // good
const str2: Path = "a.b.c" // good
const str3: Path = "a..b" // false
在 TypeScript 中,你可以使用字符串字面量类型(String Literal Types)来定义一组特定的字符串值。但是,由于字符串字面量类型只能定义一组固定的值,而不能定义具有特定模式的字符串,因此无法直接定义如 "a.b.c"
, "a.b"
这样的模式。
不过,你可以使用正则表达式或者自定义类型守卫来检查字符串是否符合你想要的路径模式。下面是一个使用自定义类型守卫的例子:
type Path = string;
function isValidPath(path: string): path is Path {
return /^[a-zA-Z_][a-zA-Z0-9_]*(\.[a-zA-Z_][a-zA-Z0-9_]*)*$/.test(path);
}
const str1: Path = "a.b";
if (!isValidPath(str1)) {
throw new Error("Invalid path");
}
const str2: Path = "a.b.c";
if (!isValidPath(str2)) {
throw new Error("Invalid path");
}
const str3: Path = "a..b";
if (!isValidPath(str3)) {
throw new Error("Invalid path");
}
在这个例子中,isValidPath
函数是一个类型守卫,它会检查一个字符串是否符合特定的路径模式。如果字符串符合模式,那么 isValidPath
函数会返回 true
,并且 TypeScript 会自动将该字符串的类型收窄为 Path
。如果字符串不符合模式,那么 isValidPath
函数会返回 false
,并且 TypeScript 会保持字符串的原始类型 string
。
注意,虽然这个例子使用了正则表达式来检查路径模式,但你可以根据自己的需要修改 isValidPath
函数。例如,你可能想要允许路径中包含数字,或者你可能想要限制路径的最大长度。
能知道类型的话可以参考element-plus
的FieldPath
https://github.com/element-plus/element-plus/blob/dev/packages/components/form/src/types.ts#L93
如果不考虑数组嵌套,可以这么写
type PathStr<T extends object, objName extends string> = {
[K in keyof T]: T[K] extends object
? K extends string
? `${objName}.${PathStr<T[K], K>}`
: never
: `${objName}.${K extends string ? K : never}`;
}[keyof T];
const test = {
a: 1,
b: 2,
c: { c1: 1, c2: 2, c3: { c31: 21, c32: "sdfasd" } },
};
type zzz = PathStr<typeof test, "test">; //type zzz = "test.a" | "test.b" | "test.c.c1" | "test.c.c2" | "test.c.c3.c31" | "test.c.c3.c32"
8 回答4.7k 阅读✓ 已解决
6 回答3.4k 阅读✓ 已解决
5 回答2.8k 阅读✓ 已解决
6 回答2.3k 阅读
5 回答6.3k 阅读✓ 已解决
4 回答2.3k 阅读✓ 已解决
4 回答2.8k 阅读✓ 已解决
不行,这个是你的业务代码,需要你自行处理。
给你一个场景就明白了:
假如从后端获取了一个数据:
const obj = { path: '名字' }
,前端能和后端约定
obj.path
是个字符串,但无法预知
字符串是否符合你的期望格式