如何实现互斥的TypeScript模板字面量类型?
实现TypeScript模板字面量类型的互斥
你定义的两个模板字面量类型中,ScreenshotsTemplate本质是PhotosTemplate的扩展结构,所以TypeScript会认为它属于PhotosTemplate的子类型,允许赋值。要让两者互斥,即PhotosTemplate仅包含**不属于ScreenshotsTemplate**的字符串,可以通过以下方式实现:
方法一:使用Exclude类型直接排除
TypeScript内置的Exclude<T, U>类型可以从T中剔除所有属于U的子类型,直接用它就能实现需求:
type PhotosTemplate = `user/${string}/photos/${string}`; type ScreenshotsTemplate = `${PhotosTemplate}/screenshots/${string}`; // 仅保留属于PhotosTemplate但不属于ScreenshotsTemplate的类型 type PhotosOnly = Exclude<PhotosTemplate, ScreenshotsTemplate>;
方法二:通过模板字面量条件约束直接定义
也可以直接在PhotosTemplate的基础上,约束最后一段字符串不包含/screenshots/${string}的结构:
type PhotosOnly = `user/${string}/photos/${string & (string extends `${infer _}/screenshots/${infer __}` ? never : string)}`;
验证效果
定义好类型后,以下代码会符合预期报错:
// 合法:属于PhotosOnly const validPhoto: PhotosOnly = "user/alice/photos/vacation"; // 报错:属于ScreenshotsTemplate,被排除在PhotosOnly之外 const invalidPhoto: PhotosOnly = "user/alice/photos/vacation/screenshots/summer";
此时PhotosOnly和ScreenshotsTemplate完全互斥,无法互相赋值,同时保留了各自原本的结构约束。
内容的提问来源于stack exchange,提问作者Refazenda
相关产品推荐
相关产品推荐

