Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there an option to make spreading an object strict?

Tags:

typescript

I was wondering if there is a compiler option or something similar to make spreading objects strict.

Please see following example to understand what I mean:

interface Foo {
  a: string;
}

interface Bar {
  a: string;
  b: number;
}

const barObject: Bar = { a: "a string", b: 1 };

// should give a warning because Bar has more properties (here b) than Foo
const fooObject: Foo = { ...barObject };

// actually prints 1
console.log((fooObject as any).b); 

Is something like this possible?

like image 317
ysfaran Avatar asked Dec 13 '19 08:12

ysfaran


People also ask

Why is it important to enable strict mode?

But first, let’s summarize why it is important to enable strict mode: The compiler is your friend — but you should make sure it can do the best for you. If it cannot infer the type of something, it cannot prevent you from doing mistakes. Turn runtime errors into compile-time errors.

What happens if you don’t use strict type checking?

But if you do not use strict type checking, the possibility to change something unintended is even greater. You will increase your productivity. Because everything has a proper type, you’ll never need to analyze the complete code flow to be sure what the type is or whether it could be null or undefined.

How to enable strict mode in angular CLI?

How To Enable Strict Mode? If you are starting with a new Angular app you can use the --strict option for Angular CLI. This will enable all available strict options in your tsconfig.json file. I have highlighted the options in charge in the following code block:

How do I Turn Off Option Strict by default?

0 Sign in to vote it would be best to leave option strict on but if you really want to turn it off then just write this on the top line of your code  option strict off also, look through your menus and in the options you should have an option to turn it off by default.


1 Answers

Interesting question. According to this issue, the result of the spread operator is intended to not trigger excess property checks.


// barObject has more props than Foo, but spread does not trigger excess property checks
const fooObject: Foo = { ...barObject };

// b is explicit property, so checks kicks in here
const foo: Foo = { ...bar, b: 2 }

There aren't exact types for TypeScript currently, but you can create a simple type check to enforce strict object spread:

// returns T, if T and U match, else never
type ExactType<T, U> = T extends U ? U extends T ? T : never : never

const bar: Bar = { a: "a string", b: 1 };
const foo: Foo = { a: "foofoo" }

const fooMergeError: Foo = { ...bar as ExactType<typeof bar, Foo> }; // error
const fooMergeOK: Foo = { ...foo as ExactType<typeof foo, Foo> }; // OK

With a helper function, we can reduce redundancy a bit:

const enforceExactType = <E>() => <T>(t: ExactType<T, E>) => t

const fooMergeError2: Foo = { ...enforceExactType<Foo>()(bar) }; // error

Code sample

like image 67
ford04 Avatar answered Dec 24 '22 08:12

ford04