typescript - 使用来自两个相似接口的默认值的对象解构
问题描述
我有两个接口,User
和BankUser
. for的界面BankUser
大致如下:
interface BankUser extends User {
banks: { [bank_id: string]: string};
isSuper: boolean;
}
我有一个函数,我要传入 aUser
或 aBankUser
并且我希望 aBankUser
从中出来。如果是用户,则应为BankUser
.
const cleanedUser = (user: User | BankUser): BankUser => {
const {uid, displayName, email, phoneNumber, photoURL, banks = {}, isSuper = false} = user;
return {uid, displayName, email, phoneNumber, photoURL, banks, isSuper} as BankUser;
}
我收到两个 TS2339 错误,表明 type 上不存在银行和 isSuper User | BankUser
,例如:
TS2339:类型上不存在属性“银行”
User | BankUser
如果我// @ts-ignore
在函数上方添加,它可以工作,我可以发送 aUser
或 a BankUser
,但如果可能的话,我会尽量避免这种情况。有没有更好的方法来处理这个?
解决方案
如果对象的类型中没有明确提及,TypeScript 不喜欢查找对象的属性。在这种情况下,User
没有明确提及banks
or isSuper
,因此您会收到编译器错误。是的, aBankUser
确实有这样的属性,但user
可能是 a User
,所以这是一个错误。
如果您想说服编译器查找该属性,则需要将其user
视为比User | BankUser
. 例如,您可以将其视为User & Partial<BankUser>
. 已知该类型具有 的所有User
属性,以及可选的来自 的额外属性BankUser
。这给了你这个:
const cleanedUser = (user: User | BankUser): BankUser => {
const {
uid, displayName, email, phoneNumber, photoURL, banks = {}, isSuper = false
} = user as User & Partial<BankUser>; // no error now
return { uid, displayName, email, phoneNumber, photoURL, banks, isSuper };
}
另外,根据您的用例,我可能会cleanedUser
这样实现:
const cleanedUser2 = (user: User | BankUser): BankUser => {
return { banks: {}, isSuper: false, ...user };
}
这需要更少的类型操作和更少的打字。它的行为与cleanedUser
假设传入的值user
恰好是aUser
或 aBankUser
并且没有额外的属性相同。
一旦您期望它user
可能具有额外的属性,那么您可能需要对这两个cleanedUser()
orcleanedUser2()
的实现更加小心,因为 type 的值User
可能具有 type 的额外isSuper
属性number
。这是完全有效的User
,但是当您进行清洁时,您会看到奇怪的事情发生:
interface Hmm extends User {
isSuper: number;
}
const hmm: Hmm = {
uid: "", email: "", displayName: "", phoneNumber: "", photoURL: "", isSuper: 100
};
const beCareful = cleanedUser(hmm);
console.log(beCareful.isSuper) // boolean at compile time, number at runtime !!!
所以要小心。
好的,希望有帮助;祝你好运!
推荐阅读
- vue.js - VueJS 将表单数据传递给子级并返回给父级的最佳实践
- python - Flask - 我的端点对用户可见吗
- python - 将数据框划分为数据框字典
- python - 使用 LSTM 进行回归 - python 和 Keras
- python - 使用带指数的输入/变量
- python - 使用 sqlalchemy 将数据插入 SQL Server db 会出现错误:“连接”对象没有属性“光标”
- python - Python - 在带有通配符的帖子中找到正确的链接
- c - 如何使用MinGW创建具有固定大小的内存段,将数据放置在段内的固定位置
- python - 在 python 中使用 selenium 根据来自 Ambari (HDFS) 的文件名下载文件
- python - UnboundLocalError:在赋值和数组之前引用了局部变量“actionNumber”