TypeScript中类型收窄的具体使用
问题描述
在 TypeScript 中,我们经常会遇到类似以下的代码和错误。
为什么下面的代码 goRoute(routers.admin) 会报错?
const routers = {
home: "/",
admin: "/admin",
user: "/user"
};
const goRoute = (r: "/" | "/admin" | "/user") => {};
goRoute(routers.admin); // 报错行: 类型"string"的参数不能赋给类型'"/" | "/admin" | "/user"'的参数。
报错如下图:

为什么会出现这个错误?
1. 类型推断机制
TypeScript 会对 routers 具体的字符串字面量类 会将对象字面量的属性类型推断为最宽泛的类型,即 string 类型。
所以 routers 的实际类型被推断为:
{
home: string;
admin: string;
user: string;
}
2. 函数参数要求具体字面量类型
goRoute 函数要求参数必须是三个具体的字符串字面量类型之一:'/' | '/admin' | '/user'。
3. 类型不匹配
当我们尝试传递 routers.admin(类型为 string)给 goRoute(需要 '/' | '/admin' | '/user')时,TypeScript 会报错,因为 string 比具体的字符串字面量类型更宽泛。
解决方案
方案 1:使用类型断言
goRoute(routers.admin as "/admin");
这种方法简单直接,但不够安全,因为如果 routers.admin 的值后来被修改,类型断言可能会掩盖真正的错误。
方案 2:声明 routers 为常量
const routers = {
home: "/",
admin: "/admin",
user: "/user"
} as const;
as const 是 TypeScript 的常量断言,它会告诉 TypeScript 将所有属性值视为字面量类型,而不是 string 类型。
此时 routers 的类型变为:
{
readonly home: '/';
readonly admin: '/admin';
readonly user: '/user';
}
方案 3:显式类型注解
interface Routes {
home: "/";
admin: "/admin";
user: "/user";
}
const routers: Routes = {
home: "/",
admin: "/admin",
user: "/user"
};
这种方法更显式地定义了类型,适合更复杂的场景。
方案 4:使用类型提取
const routers = {
home: "/",
admin: "/admin",
user: "/user"
};
type RouterValues = (typeof routers)[keyof typeof routers];
const goRoute = (r: RouterValues) => {};
这种方法动态地从 routers 对象中提取所有值的类型作为联合类型。
最佳实践
对于路由配置这种通常不会改变的结构,推荐使用 as const 方案:
const routers = {
home: "/",
admin: "/admin",
user: "/user"
} as const;
const goRoute = (r: "/" | "/admin" | "/user") => {};
goRoute(routers.admin);
这种方式的优点:
- 保持代码简洁
- 类型安全
- 易于维护(添加新路由时类型会自动更新)
- 避免硬编码类型
到此这篇关于TypeScript中类型收窄的具体使用的文章就介绍到这了,更多相关TypeScript 类型收窄内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
相关文章
用DIV完美模拟createPopup 弹出窗口(脚本之家修正版),支持Firefox,ie,chrome
最近要重构公司的一个站,有一个拾色器只支持IE,不支持FIREFOX CHROME等浏览器,花了点时间对照原来的重写了个。完美实现createPopup方法的弹窗效果,欢迎大家拍砖!2009-09-09
JavaScript常用的返回,自动跳转,刷新,关闭语句汇总
这篇文章主要介绍了JavaScript常用的返回,自动跳转,刷新,关闭语句,实例汇总了常用的javascript技巧,非常具有实用价值,需要的朋友可以参考下2015-01-01
js基于FileSaver.js 浏览器导出Excel文件的示例
本篇文章主要介绍了js基于FileSaver.js 浏览器导出Excel文件的示例,具有一定的参考价值,有兴趣的可以了解一下2017-08-08
一篇文章详细讲解JavaScript中的this(普通函数、箭头函数、 函数运用)
这篇文章主要介绍了JavaScript中this关键字的指向规则,包括全局环境、函数、对象方法、构造函数、事件处理函数和箭头函数中的this指向,文中通过代码介绍的非常详细,需要的朋友可以参考下2025-04-04


最新评论