Skip to content

Synthesized optional properties don't satisfy Record< target under EOPT: falseΒ #59180

Open

Description

πŸ”Ž Search Terms

switch map array narrow

πŸ•— Version & Regression Information

I went back to TS 4 - still present

⏯ Playground Link

https://www.typescriptlang.org/play/?#code/KYDwDg9gTgLgBDAnmYcBiBLANjYUAKAhlIQLYBqhWArqgLxwDOMUGAdgOZwA+cb1pAEZ4ecACKFco5q04BtALoBuALAAodaEiw47XFABmhAMaoAkphx4APABU4oXGwAmjJi3YcAfHADe6uEC+MmAALjhbVTUguDBiMkYAfnCAJWBjaGdrGU8AGnRsfSISCipaLyiAX3VNcGh4PTwjUzgzACFCRgxjS30AZWAOUmA2GDsHECdXd1lvCam3C0KbWx9-aKCkFHCAcgNlqB2qmrUteoRkc168AaGRsftHEemczh8GJasoW+HRgFFwFBgIwuhA2HYfLx2p1utdvoNfg8KrVtPAtqgfvcAPIoEgwaBwBg7QguHaiHbQI4o86NQwmK4HTH-QHA0Hgx6TZ5uV5zdYxdHhJkwHF4STQKIxMBA5zdSTA8KffoI+4QxTHDSnfikApfAByITcfgCQQ6UDMbiJgmIAH0MIwdrljYEOgAvc2EuA7K0u2329TVDUjATiDC-Nm2S5GjbO4ger3EB1OuCuuPenb+k5nHTo1piUMjNkevlBDDOcI8iWbS7hPNhjBgiMoAB0pqqomLgVL5Y8nErgSwhGEWG7sz7F22IbrDcuLcILqqUXUGTYzAQJBXBmg2oYAAoZVOVwrawX62xFABKBVwoXWOH64aMd5rJNAmDUKBsKMxfnVz0k5yJtG35SsAMrGHKjDhPuJ5gowTakIQYB7vmK6noSz5Ad+QSMAA7hgMDGAAFnAyEHk26Lnl+WHUYE4GMKgx6odOzamuEHY0Rxr7vp+7EcXx45hJ6+xfIB-FicEwzhHeBqzmajCOph4lYXEJSQVRSliVaZplnA0FMWwTalkmGnfgGJkxGZGmWUpdEMSh4Yzq6bHGRpXEfup5k-hOewHKJnnfmwIRSQc97ArObryS5nkqQkzmKf5QTemYOl6WyhnOFF5nWVlmU0dleWZZU55JgGlRAA

πŸ’» Code

export type FilterParamValue = string | number | Date | string[];

export interface IFilter<T extends string> {
    name: T;
    params?: Record<string, FilterParamValue>;
}

export interface IBasicFilterSegment<T extends string> extends IFilter<T> {
    type: 'filter';
}

export type IFilterSegment<T extends string> = IFilterSegmentExpression<T> | IBasicFilterSegment<T>;
export type SegmentOperator = 'and' | 'or';
export interface IFilterSegmentExpression<T extends string> {
    type: SegmentOperator;
    predicates: IFilterSegment<T>[];
}

enum FilterNames  {
    BarIs = 'bar_is',
    BazIs = 'baz_is'
}

enum DimensionType {
    Bar = 'bar',
    Baz = 'baz'
}

export type IDimension = {
    id: string;
    type: DimensionType.Bar;
} | {
    id: string;
    label: string;
    type: DimensionType.Baz;
};

const transform = (dimensions: IDimension[]): IFilterSegment<FilterNames> => {
    return {
        type: 'and',
        predicates: dimensions.map(dimension => {
            switch (dimension.type) {
                case DimensionType.Bar: {
                    return {
                        type: 'filter',
                        name: FilterNames.BarIs,
                        params: {
                            barId: dimension.id
                        }
                    }
                }
                case DimensionType.Baz: {
                    return {
                        type: 'filter',
                        name: FilterNames.BazIs,
                        params: {
                            bazId: dimension.id
                        }
                    }
                }
            }
        })
    }
}

πŸ™ Actual behavior

A compile-time error is displayed. It appears that the fact that we might return in the first switch case is "carried over" to the second one.

πŸ™‚ Expected behavior

Type narrowing to work correctly as the mapping is correct. In fact, if one extracts this mapping to a separate function, the behaviour is fixed. Playground.

Additional information about the issue

No response

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

No one assigned

    Labels

    Experimentation NeededSomeone needs to try this out to see what happensSuggestionAn idea for TypeScript

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions