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?
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.
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? 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:
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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With