You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I'm trying to create a helper function to simplify self-assignment of values from an object provided by my applications rxjs + redux based store.
The helper function should cause a compile error if the object picked from the store contains properties that do not exist on the target object. Code and details can be found below.
TypeScript Version: 3.1.3
All available flags extending strictness are enabled except strictPropertyInitialization, and suppressImplicitAnyIndexErrors suppresses some errors.
Search Terms: type checking
Code
A stripped-down example of what I'm trying to achieve:
classA{gammel: string="42";methodB(){// [1] Fails correctly for property "test" - does not exists on class.selfExtend(this)({gammel: "5",test: 14});// [2] Does not fail, even though it's the same data.consto={gammel: "5",test: 14};selfExtend(this)(o);}}// Cheap trick to get around an issue with Partial<this>,// which is acceptable in our case.typeIdentity<T>={[PinkeyofT]: T[P];};exportfunctionselfExtend<Textendsobject>(target: Identity<T>){returnfunction(data: Partial<Identity<T>>|null){if(data){// In case the type-check is correct, the keys from `Object.getOwnPropertyNames`// should exist in both `data` and `target` - thus, assignment is safe. Object.getOwnPropertyNames(data).forEach(k=>(target[k]=data[k]));}};}
Expected behavior:
In the code above, both case [1] and [2] (see comments) should cause an error that test does not exist on the target object.
Actual behavior:
Only case [1] fails, case [2] is accepted by the type checker. I.e.: Assigning the malformed value to a variable before using it causes the type check to fail, while providing the object anonymously works fine.
I think this is down to excess property checks. In [1] the literal has a contextual type from the function parameter. In [2] the literal is created without a contextual type, so there are no excess properties to look for. If you put an annotation on the declaration of o you get a similar error.
consto: Partial<Identity<A>>={gammel: "5",test: 14// ^^^^^^^^// Type '{ gammel: string; test: number; }' is not assignable to type 'Partial<Identity<A>>'.// Object literal may only specify known properties, and 'test' does not exist in type 'Partial<Identity<A>>'.};selfExtend(this)(o);
That is precisely what is happening. By omittig the type annotation the compiler will infer the type for o, and that type is: { gammel: string; test: number; }. This has no excess properties. When passing it to the selfExtend(this) it will then just check if the argument o is compatible with the argument type, which it is.
Thanks for pointing me in this direction - didn't have the excess property check in mind.
Tried to minimize to code used for that assignment as much as possible, but it seems this need some additional checks or a different way to properly determine the types and achieve useful errors.
I'm trying to create a helper function to simplify self-assignment of values from an object provided by my applications rxjs + redux based store.
The helper function should cause a compile error if the object picked from the store contains properties that do not exist on the target object. Code and details can be found below.
TypeScript Version: 3.1.3
All available flags extending strictness are enabled except
strictPropertyInitialization
, andsuppressImplicitAnyIndexErrors
suppresses some errors.Search Terms: type checking
Code
A stripped-down example of what I'm trying to achieve:
Expected behavior:
In the code above, both case [1] and [2] (see comments) should cause an error that
test
does not exist on the target object.Actual behavior:
Only case [1] fails, case [2] is accepted by the type checker. I.e.: Assigning the malformed value to a variable before using it causes the type check to fail, while providing the object anonymously works fine.
Playground Link:
Playground can be found here.
Related Issues:
Found some with similar, but not identical problems:
#27497
#26045
#17667
The text was updated successfully, but these errors were encountered: