最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - TypeScript misunderstanding. How to fix problem? - Stack Overflow

programmeradmin3浏览0评论

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
  • • Excess properties are generally allowed; what do you think needs to be "fixed" here? All of your objects have the properties they are required to have. (Nothing is missing.) If you have a concern about allowing extra properties, please edit to spell that out because it's not clear and TS doesn't work that way. What, exactly, goes wrong if you allow thirdObjectFull to have extra properties? – jcalz Commented Mar 7 at 20:57
Add a comment  | 

2 Answers 2

Reset to default 1

TS 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

发布评论

评论列表(0)

  1. 暂无评论