Search code examples
stringtypescripttypestypescript-never

Typescript Type 'string' is not assignable to type 'never'. error


What I wanna do is so simple.

In the example below,

interface InterfaceA { a: string, b: number }
interface InterfaceB { c: keyof InterfaceA }

const testMethod = (test: InterfaceB) => {
      const TestObject: InterfaceA = { a: '', b: 1 }

      TestObject[test.c] = 
    }

causes 'Type 'any' is not assignable to type 'never'' error.

I thought that test.c can be assigned in TestObject since c is the key of Interface A.

How can I make things work?


Solution

  • You are receiving this error because the type of test.c can not be narrowed down any more than keyof InterfaceA. In other words, if we try to assign to TestObject[test.c] typescript wont be able to determine if we need to assign a string or a number. So it determines that the type must be all valid types at the same time, in this case number & string. However no value can be both a number and a string at the same time, so the resulting type ends up being never (See this playground for an example).

    We can solve this by helping typescript narrow down the actual type of test.c like this:

    interface InterfaceA { 
        a: string, 
        b: number
    }
    interface InterfaceB { 
        c: keyof InterfaceA
    }
    
    const testMethod = (test: InterfaceB) => {
        const TestObject: InterfaceA = { a: '', b: 1 }
    
        switch (test.c) {
            case 'a':
                TestObject[test.c] = 'foo';
                break;
            case 'b':
                TestObject[test.c] = 42;
                break;
        }
    }
    

    playground