以下代码段未通过类型检查:
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
造成这种情况的原因是什么?如何解决?
答案 0 :(得分:8)
只有在将字符串文字类型分配给const
时,它才会推断字符串文字类型。在创建对象文字时,编译器将推断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'
};
})
您也可以直接在返回值上键入assert,但这会禁用对返回值的一些检查:
const tasks:TaskDefinition[] = ["apples", "pears"].map(i => {
return <TaskDefinition>{
wrongValue: "", // no error since we are asserting
name: i,
task: i,
taskType: 'SIMPLE'
};
})
答案 1 :(得分:3)
编译器没有将'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
};
});
答案 2 :(得分:2)
我看到了解决这个问题的三种方法:
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
};
});
至于为什么,我不完全确定。为什么不使用字符串枚举代替自定义字符串类型?