我有两个接口,User
和BankUser
。 BankUser
的界面大致如下:
interface BankUser extends User {
banks: { [bank_id: string]: string};
isSuper: boolean;
}
我有一个要传递User
或BankUser
的函数,并且我希望BankUser
从中传递出来。如果是用户,则应为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错误,指示类型User | BankUser
上不存在bank和isSuper,例如:
TS2339:属性“银行”在类型
User | BankUser
上不存在
如果我在函数上方添加// @ts-ignore
,它可以工作,并且我可以发送User
或BankUser
,但是我尽量避免这样做。有更好的方法来解决这个问题吗?
答案 0 :(得分:0)
如果没有在对象的类型中明确提及该对象,则TypeScript不喜欢查找该对象的属性。在这种情况下,User
没有明确提及banks
或isSuper
,因此会出现编译器错误。是的,BankUser
确实具有这样的属性,但是user
可能是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
或User
,并且它没有{额外的属性。
一旦您期望BankUser
可能具有额外的属性,那么您可能需要更加小心user
或cleanedUser()
的实现,因为类型为{{1} }可能具有类型cleanedUser2()
的额外User
属性。这是一个非常有效的isSuper
,但是当您进行清洁时,您会发现奇怪的事情发生了:
number
所以要小心。
好的,希望能有所帮助;祝你好运!