Typescript type inference, spread syntax and multiple type return

622 views Asked by At
interface SkillProperty {
    [name: string] : number 
};

let skills: SkillProperty;

skills = {}; // ok

skills = { fire: 123 }; // ok

skills = {
    ...skills, // ok
    ...{}, // ok
    ...extraSkills() // {} | { ice: number } is not assignable to type 'SkillProperty'.
}

function extraSkills() {
    if (whatever) {
        return {};
    }
    return { ice: 321 };
}

How can I change my SkillProperty interface to make it compliant with both empty object and my actual SkillProperty type ?

1

There are 1 answers

1
jcalz On BEST ANSWER

Your SkillProperty interface is actually compatible with {} | {ice: number}:

let noSkills = {}
let iceSkills = { ice: 321 };
let randomSkills: {} | {ice: number} = (Math.random() < 0.5) ? noSkills : iceSkills
let maybeSkills: SkillProperty = randomSkills; // no error

So, this looks like a bug in TypeScript to me. A similar issue was fixed, but this case seems to persist. It might be worthwhile opening a new issue with links to those existing ones.

In the mean time there are workarounds, like:

skills = {
  ...skills, // ok
  ...{}, // ok
  ...extraSkills() as SkillProperty // okay now
}

Hope that helps; good luck!