Search code examples
typescriptobjecttypescompiler-errorstype-conversion

Why can't an interface be assigned to Record<string, unknown>?


I just noticed that an interface cannot be assigned to Record<string, unknown> (playground link):

interface Foo {
    foo: number
}

const foo: Foo = { foo: 1 }
const bar: Record<string, unknown> = foo
//    |-> Error: Type 'Foo' is not assignable to type 'Record<string, unknown>'
//               Index signature is missing in type 'Foo'.(2322)

However the same is possible, when the type declaration for Foo is omitted (playground link):

const foo = { foo: 1 }
const bar: Record<string, unknown> = foo // no error here

Question: Why is there a difference between both examples? For me the reduced type of the variable foo is the same in both examples... Shouldn't the interface Foo be assignable to Record<string, unknown>?

In my understanding Record<string, unknown> is equivalent to object and thus any interface should be assignable to it. Also @typescript-eslint/ban-types suggests using Record<string, unknown> instead of object.

Remarks: The first example works when either object (playground link) or Record<string, any> (playground link) is used instead of Record<string, unknown>.


Solution

  • You've run across Index signature is missing in type (only on interfaces, not on type alias) #15300

    The code will work when you change an interface to a type:

    type Foo = {
        foo: number
    }
    
    const foo: Foo = { foo: 1 };
    const bar: Record<string, unknown> = foo;