typescript - 我可以使对象属性类型依赖于另一种属性类型吗?
问题描述
我有一个看起来像这样的对象:
interface AuthState {
isSignedIn: boolean
token?: string
user?: User
}
user
可以是未定义的,但仅当isSignedIn === false
. 在应用程序中不可能有isSignedIn === true
也没有用户对象。我希望能够强制执行并避免必须执行以下操作:
// If I don't check for `user`, TS will throw an error since it doesn't see any
// relation between the 2 properties
const userName = isSignedIn && user && user.name
解决方案
如果我理解你的问题,这应该是你要找的。
interface FalseAuthState {
isSignedIn: false;
}
interface TrueAuthState {
isSignedIn: true;
token: string;
user: User;
}
type AuthState = FalseAuthState | TrueAuthState;
所以现在,如果你有一个像
// This does not throw an error because Typescript knows it's correct
const noAuth: AuthState = {
isAuth: false
}
// This will throw an error because Typescript demands a User and Token.
const yesAuth: AuthState = {
isAuth: true
}
// This will not throw an error.
const realAuth: AuthState = {
isAuth: true,
token: "ABCD123",
user: new User()
}
function printUser(auth: AuthState) {
if (auth.isAuth) {
console.log(auth.user); // Typescript knows there's supposed to be a user so there is no error
}
}
function badPrintUser(auth: AuthState) {
if (auth.isAuth === false) {
console.log(auth.user); // Typescript will throw an error because there's no supposed to be a user here.
}
}
在您的示例中,您检查的方式如下:
const userName = auth.isSignedIn && auth.user.name
或者
const userName = auth.isSignedIn ? auth.user.name : undefined;
不幸的是,您将无法从对象本身中删除属性并将其用于您的优势。如果你要这样做
const { isSignedIn, user } = (auth as TrueAuthState);
const userName = isSignedIn && user && user.name; // You still have to do this unless you really sure that the auth is a TrueAuthState
推荐阅读
- android - 在颤振中构建 appbundle 时出现错误
- c# - 实体框架:如何基于现有属性添加关联
- python - 在python中实现rot13
- javascript - 无法将外部 JavaScript 文件添加到 React 应用程序
- azure-data-factory - 如何使用 Azure 数据工厂服务的 Web Activity 将实体插入 Azure 存储表
- sql-server - SSMS“新建数据库”选项不出现
- package - 安装 wxpython 的故障?
- sql - 如果公式值大于 20,则返回 20,否则返回公式值
- linux - Linux bash 上有没有办法突出显示在当前路径的最后 N 分钟内修改的所有文件
- java - Android应用程序在最小化然后打开后崩溃