考慮以下代碼:
interface IUserData {
FirstName: string,
LastName: string,
Email: string,
Password: string
}
interface IState extends IUserData {
isSuccess: boolean
}
const state: IState = {
FirstName: 'Jan',
LastName: 'Kowalski',
Email: 'email',
Password: 'abc',
isSuccess: true
}
const testFunction = (userData: IUserData): void => {
console.log(userData);
}
testFunction(state)
代碼回傳:
{
FirstName: 'Jan',
LastName: 'Kowalski',
Email: 'email',
Password: 'abc',
isSuccess: true
}
問題是為什么函式甚至接受state物件。我希望編譯器至少會拋出引數型別不正確的錯誤。
對此進行測驗,我想看看是否有可能將一個物件提供給函式,該物件的屬性是原始物件屬性的子集,而無需將它們映射到新物件。
簡而言之,所需的輸出是:
{
FirstName: 'Jan',
LastName: 'Kowalski',
Email: 'email',
Password: 'abc',
}
uj5u.com熱心網友回復:
我希望編譯器至少會拋出引數型別不正確的錯誤。
引數型別是正確的。IState是一種亞型的IUserData,所以任何地方,你可以使用IUserData,你可以使用IState。這是物件型別層次結構的標準,不僅在 TypeScript 中,而且在 Java、C# 和許多其他中都是如此。(打字稿使得一個例外一般規則:當你將指定為物件字面的東西[let x: ABCType = {a: 1, b: 2, c: 3, d: 4};其中ABCType只有a,b和c]或類似的使用物件文本,用于在功能呼叫的引數時,它警告你的“過剩屬性”——不是因為從型別的角度來看它是不正確的,而是因為從實用的角度來說,它可能是一個編碼錯誤。)
簡而言之,所需的輸出是:
{ FirstName: 'Jan', LastName: 'Kowalski', Email: 'email', Password: 'abc', }
您正在記錄函式收到的引數值。您的代碼中沒有任何內容可以修改或提取該物件的屬性,因此該物件的所有屬性(包括來自其子型別的屬性)都存在。
TypeScript 不對values做任何事情,這是運行時的事情,而 TypeScript 是編譯時的事情(除了小的運行時存在enum)。如果要撰寫一個洗掉多余屬性的函式,則必須使用運行時代碼顯式執行此操作。TypeScript 不會為你做這件事。(遺憾的是,在從型別定義中獲取屬性名稱的情況下是不可能的,您必須以另一種方式來實作:從實際存在于運行時的模型物件中派生型別定義。)
這是一個這樣做的例子(我不是推薦它,我只是告訴你如果你想怎么做):
const sampleUserData = {
FirstName: "Jan",
LastName: "Kowalski",
Email: "email",
Password: "abc",
};
type IUserData = typeof sampleUserData;
const userDataKeys = new Set(Object.keys(sampleUserData));
const testFunction = (userData: IUserData): void => {
// Filter out non-IUserData properties
const filtered = Object.fromEntries(
Object.entries(userData).filter(([key]) => userDataKeys.has(key))
) as IUserData;
console.log(filtered);
};
然后這個:
interface IState extends IUserData {
isSuccess: boolean
}
const state: IState = {
FirstName: "Jan",
LastName: "Kowalski",
Email: "email",
Password: "abc",
isSuccess: true
};
testFunction(state);
日志:
{
"FirstName": "Jan",
"LastName": "科瓦爾斯基",
"電子郵件": "電子郵件",
“密碼”:“abc”
}
游樂場鏈接
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/326523.html
