使用 TypeScript 更新物件屬性
我正在嘗試從一個物件動態更新一個帶有選項屬性的物件。在代碼中,我遇到了一個錯誤,錯誤顯示 axiosOptions.headers[key](我在下面的代碼示例中留下了註解)。
TypeScript 錯誤
Type 'string | undefined' is not assignable to type '"true" | "false"'.
Type 'undefined' is not assignable to type '"true" | "false"'.
我的程式碼
type ApiHeaders = {
Accept: string;
'Content-Type': string;
IsRequireAdmin: 'true' | 'false';
Authorization?: string;
BarCode?: string;
DomainName?: string;
};
interface AxiosOptions {
params?: any;
data?: any;
headers: ApiHeaders;
}
const axiosOptions: AxiosOptions = {
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
IsRequireAdmin: 'false'
}
};
const updateAxiosOptionsHeaders = (newApiHeaders: Partial<ApiHeaders>): void => {
let key: keyof Partial<ApiHeaders>;
for (key in newApiHeaders) axiosOptions.headers[key] = newApiHeaders[key]; // <----------- typescript error
};
const token: string = 'my_token';
const barCode: string = 'my_bar_code';
const domainName: string = 'www.mydomain.com';
const newApiHeaders: Omit<ApiHeaders, 'Content-Type' | 'Accept'> = {
'IsRequireAdmin': 'true',
'Authorization': `Bearer ${token}`,
'BarCode': barCode,
'DomainName': `DATA\\${domainName}`
};
updateAxiosOptionsHeaders(newApiHeaders);
我對如何解決這個問題持開放態度,願意聽取建議。
答案#1
TypeScript 不知道它不知道的東西。它不知道在任何一次執行 updateAxiosOptionsHeaders 時 key 會是什麼,所以它選擇了最嚴格的可能解釋。當然,有很多不同的方法可以解決這個問題,但如果你想保持類型不變,你可以在函數中這樣做來解決它:
type ApiHeaders = {
Accept: string;
'Content-Type': string;
IsRequireAdmin: 'true' | 'false';
Authorization?: string;
BarCode?: string;
DomainName?: string;
};
interface AxiosOptions {
params?: any;
data?: any;
headers: ApiHeaders;
}
const axiosOptions: AxiosOptions = {
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
IsRequireAdmin: 'false'
}
};
const updateAxiosOptionsHeaders = (newApiHeaders: Partial<ApiHeaders>): void => {
let key: keyof Partial<ApiHeaders>;
for (key in newApiHeaders) {
if (key === 'IsRequireAdmin') {
// Note the default value if one isn't provided in newApiHeaders for some reason
axiosOptions.headers.IsRequireAdmin = newApiHeaders.IsRequireAdmin ?? 'false';
} else {
// ditto here
axiosOptions.headers[key] = newApiHeaders[key] ?? '';
}
}
};
const token: string = 'my_token';
const barCode: string = 'my_bar_code';
const domainName: string = 'www.mydomain.com';
const newApiHeaders: Partial<ApiHeaders> = {
'IsRequireAdmin': 'true',
'Authorization': `Bearer ${token}`,
'BarCode': barCode,
'DomainName': `DATA\\${domainName}`
};
updateAxiosOptionsHeaders(newApiHeaders);
查看已更改部分的評論;你需要決定合理的預設值。
答案#2
你需要允許 undefined。這是在宣告類型時完成的,而不是在類型轉換時。見下文。
type ApiHeaders = {
Accept: string;
'Content-Type': string;
IsRequireAdmin: 'true' | 'false' | undefined;
Authorization?: string;
BarCode?: string;
DomainName?: string;
};
