[英]Typescript - Why can't this string literal type be inferred?
以下代碼段未通過類型檢查:
type TaskType = 'SIMPLE' | 'COMPLEX'
interface TaskDefinition {
name: string,
task: string,
taskType: TaskType
};
const test: TaskDefinition = {
name: '',
task: '',
taskType: 'SIMPLE' // This is fine
};
const tasks : TaskDefinition[] = ["apples", "pears"].map(i => {
return {
name: i,
task: i,
taskType: 'SIMPLE' // This one is not
};
})
{name:string; 任務:字符串; taskType:string; } [] 不能分配給TaskDefinition []類型。
看來, taskType
被推斷為string
,而不是TaskType
,盡管目標類型是TaskDefinition
造成這種情況的原因是什么?如何解決?
只有在將它分配給const
時,Typescript才會推斷出字符串文字類型。 在創建對象文字時,編譯器將推斷字符串常量的string
而不是字符串文字類型。 如果將對象文字直接分配給需要字符串文字類型的東西,那就沒問題,因為在這種情況下,編譯器只檢查字符串常量是否可賦值給字符串文字類型。
這里的簡單解決方案是指定要map
的類型參數,這仍將保留編譯器對map
返回值的檢查:
const tasks = ["apples", "pears"].map<TaskDefinition>(i => {
return {
name: i,
task: i,
taskType: 'SIMPLE'
};
})
或者在字符串上使用類型斷言到期望的字符串文字類型:
const tasks:TaskDefinition[] = ["apples", "pears"].map(i => {
return {
name: i,
task: i,
taskType: 'SIMPLE' as 'SIMPLE'
};
})
編輯從typescript 3.4( PR )開始,您還可以使用as const
斷言來獲取字符串文字類型:
const tasks:TaskDefinition[] = ["apples", "pears"].map(i => {
return {
name: i,
task: i,
taskType: 'SIMPLE' as const
};
})
結束編輯
您也可以直接在返回值上鍵入assert,但這將禁用對返回值的一些檢查:
const tasks:TaskDefinition[] = ["apples", "pears"].map(i => {
return <TaskDefinition>{
wrongValue: "", // no error since we are asserting
name: i,
task: i,
taskType: 'SIMPLE'
};
})
編譯器沒有將'SIMPLE'
從字符串縮小到TaskType,因此您需要使用類型斷言來幫助它。 有兩種選擇。
const tasks: TaskDefinition[] = ["apples", "pears"].map(i => {
return <TaskDefinition> {
name: i,
task: i,
taskType: 'SIMPLE' // This one is not
};
});
const tasks: TaskDefinition[] = ["apples", "pears"].map(i => {
return {
name: i,
task: i,
taskType: <TaskType>'SIMPLE' // This one is not
};
});
我看到了解決這個問題的三種方法:
return {
name: i,
task: i,
taskType: 'SIMPLE'
} as TaskDefinition;
要么:
const tasks: TaskDefinition[] = ["apples", "pears"].map(i => {
return {
name: i,
task: i,
taskType: 'SIMPLE'
};
}) as TaskDefinition[];
要么:
const tasks: TaskDefinition[] = ["apples", "pears"].map(i => {
return {
name: i,
task: i,
taskType: 'SIMPLE' as TaskType
};
});
至於為什么,我不完全確定。 為什么不使用字符串枚舉代替自定義字符串類型?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.