打字稿 - 为什么不能推断出这个字符串文字类型?

ᴘᴀɴ*_*ᴛɪs 6 types literals typescript

以下代码段未通过类型检查:

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
    };
})
Run Code Online (Sandbox Code Playgroud)

{name:string; 任务:字符串; taskType:string; } [] 不能赋值TaskDefinition [].

试试吧

尽管目标类型存在,但它似乎taskType被推断为string而不是TaskTypeTaskDefinition

造成这种情况的原因是什么?如何解决?

Tit*_*mir 9

只有在将字符串文字分配给a时,Typescript才会推断字符串文字类型const.在创建对象文字时,编译器将推断string字符串常量而不是字符串文字类型.如果将对象文字直接分配给需要字符串文字类型的东西,那就没问题,因为在这种情况下,编译器只检查字符串常量是否可赋值给字符串文字类型.

这里的简单解决方案是指定类型参数map,这仍将保留编译器对返回值的检查map:

const tasks = ["apples", "pears"].map<TaskDefinition>(i => {
    return {
        name: i,
        task: i,
        taskType: 'SIMPLE'
    };
})
Run Code Online (Sandbox Code Playgroud)

或者在字符串上使用类型断言到期望的字符串文字类型:

const tasks:TaskDefinition[] = ["apples", "pears"].map(i => {
    return {
        name: i,
        task: i,
        taskType: 'SIMPLE' as 'SIMPLE'
    };
}) 
Run Code Online (Sandbox Code Playgroud)

您也可以直接在返回值上键入assert,但这将禁用对返回值的一些检查:

const tasks:TaskDefinition[] = ["apples", "pears"].map(i => {
    return {
        name: i,
        task: i,
        taskType: 'SIMPLE' as const
    };
}) 
Run Code Online (Sandbox Code Playgroud)