Search code examples
node.jstypescriptinterface

Typescript interface with spread syntax


I was trying to make an interface and initialize its instance with another object properties by spread syntax. I found something weird and wanted to find out why this can happen.

This is an example of what I want.

A: The object that I want to make as a result

A = {  a: number, b: number, c: number, d: number }

B: The object I've got with DB query

B = {a: number,b: number,c: number,e: string}

C: The object that has a value I will insert manually

C = { d: boolean }

So I've declared an interface A, and used spread syntax to make an object of A with B object.

A_object = {...B_object }

What I expected was an object of A which has properties 'a', 'b', and 'c', or an error. But the result was quite different. Property 'e' also appeared, which doesn't exist in interface A.
Can anybody explain why this happens?

test screenshot


Solution

  • The spread operator is a JavaScript feature which does not know about the known properties of TypeScript-interfaces. All properties of B_object will therefore appear in A_object when A_object = { ...B_object }.

    From a type-safety perspective, this is fine. Everything needed to construct a valid A instance is also present in B, so spreading B into A is considered to be valid.

    You are probably looking for excess property checks. Those are not necessarily needed in a structural type system and there are only a select few places where TypeScript does perform them. And spreading objects is not one of those places. There is an open Issue requesting this and you can give it a thumbs up if you want to see it implemented.