簡體   English   中英

打字稿 - 為什么不能推斷出這個字符串文字類型?

[英]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,因此您需要使用類型斷言來幫助它。 有兩種選擇。

在Object處鍵入Assertion

const tasks: TaskDefinition[] = ["apples", "pears"].map(i => {
    return <TaskDefinition> {
        name: i,
        task: i,
        taskType: 'SIMPLE' // This one is not
    };
});

在值處鍵入Assertion

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM