Have a code (typescriptPlayground)
problem is in spread operator. in case of secondObjectFull i have an error. It is ok. firstObject cannot spread to secondFullMapped
But in case of thirdObjectFull i can spread firstObject to thirdFullMapped. I think that because of definition of thirdFullMapped
type thirdMapped = MappedTypeFunc<Omit<third, keyof base>, any>
type thirdFullMapped = baseMapped & thirdMapped;
in this case thirdMapped is empty. I think a problem is becase of this. If thirdMapped is not empty - all work as expected.
How to fix this situation?
Code:
interface base {
type: string;
name: string;
add: string;
}
interface first extends base {
firstProp: string
}
interface second extends base {
secondProp: string
}
interface third extends base {
}
type MappedTypeFunc<T, U> = {
[K in keyof T]: (value: T[K], additionalParam?: U) => any;
}
type baseMapped = MappedTypeFunc<base, any>
type firstMapped = MappedTypeFunc<Omit<first, keyof base>, any>
type firstFullMapped = baseMapped & firstMapped;
type secondMapped = MappedTypeFunc<Omit<second, keyof base>, any>
type secondFullMapped = baseMapped & secondMapped;
type thirdMapped = MappedTypeFunc<Omit<third, keyof base>, any>
type thirdFullMapped = baseMapped & thirdMapped;
const baseObject: baseMapped = {
type: function (value: string, additionalParam?: any) {
throw new Error("Function not implemented.");
},
name: function (value: string, additionalParam?: any) {
throw new Error("Function not implemented.");
},
add: function (value: string, additionalParam?: any) {
throw new Error("Function not implemented.");
}
}
const firstObject: firstMapped = {
firstProp: function (value: string, additionalParam?: any) {
throw new Error("Function not implemented.");
}
}
const secondObject: secondMapped = {
secondProp: function (value: string, additionalParam?: any) {
throw new Error("Function not implemented.");
}
}
const thirdObject: thirdMapped = {}
const firstObjectFull: firstFullMapped = {
...baseObject,
...firstObject
}
// error - OK
const secondObjectFull: secondFullMapped = {
...baseObject,
...firstObject
}
// No error on spread firstObject why???
const thirdObjectFull: thirdFullMapped = {
...baseObject,
...firstObject
}
Have a code (typescriptPlayground)
problem is in spread operator. in case of secondObjectFull i have an error. It is ok. firstObject cannot spread to secondFullMapped
But in case of thirdObjectFull i can spread firstObject to thirdFullMapped. I think that because of definition of thirdFullMapped
type thirdMapped = MappedTypeFunc<Omit<third, keyof base>, any>
type thirdFullMapped = baseMapped & thirdMapped;
in this case thirdMapped is empty. I think a problem is becase of this. If thirdMapped is not empty - all work as expected.
How to fix this situation?
Code:
interface base {
type: string;
name: string;
add: string;
}
interface first extends base {
firstProp: string
}
interface second extends base {
secondProp: string
}
interface third extends base {
}
type MappedTypeFunc<T, U> = {
[K in keyof T]: (value: T[K], additionalParam?: U) => any;
}
type baseMapped = MappedTypeFunc<base, any>
type firstMapped = MappedTypeFunc<Omit<first, keyof base>, any>
type firstFullMapped = baseMapped & firstMapped;
type secondMapped = MappedTypeFunc<Omit<second, keyof base>, any>
type secondFullMapped = baseMapped & secondMapped;
type thirdMapped = MappedTypeFunc<Omit<third, keyof base>, any>
type thirdFullMapped = baseMapped & thirdMapped;
const baseObject: baseMapped = {
type: function (value: string, additionalParam?: any) {
throw new Error("Function not implemented.");
},
name: function (value: string, additionalParam?: any) {
throw new Error("Function not implemented.");
},
add: function (value: string, additionalParam?: any) {
throw new Error("Function not implemented.");
}
}
const firstObject: firstMapped = {
firstProp: function (value: string, additionalParam?: any) {
throw new Error("Function not implemented.");
}
}
const secondObject: secondMapped = {
secondProp: function (value: string, additionalParam?: any) {
throw new Error("Function not implemented.");
}
}
const thirdObject: thirdMapped = {}
const firstObjectFull: firstFullMapped = {
...baseObject,
...firstObject
}
// error - OK
const secondObjectFull: secondFullMapped = {
...baseObject,
...firstObject
}
// No error on spread firstObject why???
const thirdObjectFull: thirdFullMapped = {
...baseObject,
...firstObject
}
Share
edited Mar 27 at 14:18
VLAZ
29.2k9 gold badges63 silver badges84 bronze badges
asked Mar 7 at 19:57
Andrew MAndrew M
254 bronze badges
1
|
2 Answers
Reset to default 1TS doesn't enforce strict type checking when using spread syntax on object literals when initializing variable. So you can add any additional properties that way. The error on the first object isn't that ...firstObject
is used, but secondProp
is missing. The third is complete despite of additional props added with ...firstObject
so no error.
A first solution that came to mind isn't elegant:
Playground
ThirdMapped is {} that is not empty object but object, anything not null or undefined.
You can do something you can try to solve it with: type EmptyObject = Record<string, never>; type NormalizeEmpty = keyof T extends never ? EmptyObject : T;
gl
thirdObjectFull
to have extra properties? – jcalz Commented Mar 7 at 20:57