Skip to content

Method overloads are often frustrating for me #40827

Closed
@bpasero

Description

@bpasero

TypeScript Version: 4.0.x
Search Terms: overload

Code

enum SideBySideEditor {
    PRIMARY,
    SECONDARY,
    BOTH
}

interface URI { }

interface IEditorInput { }

interface IResourceOptions {
    supportSideBySide?: SideBySideEditor;
}

function toResource(editor: IEditorInput | undefined | null): URI | undefined;
function toResource(editor: IEditorInput | undefined | null, options: IResourceOptions & { supportSideBySide?: SideBySideEditor.PRIMARY | SideBySideEditor.SECONDARY }): URI | undefined;
function toResource(editor: IEditorInput | undefined | null, options: IResourceOptions & { supportSideBySide: SideBySideEditor.BOTH }): URI | { primary?: URI, secondary?: URI } | undefined;
function toResource(editor: IEditorInput | undefined | null, options?: IResourceOptions): URI | { primary?: URI, secondary?: URI } | undefined {
    // Method implementation left out for brevity.
    return undefined;
}

export function getOriginalUri(editor: IEditorInput | undefined | null): URI | undefined;
export function getOriginalUri(editor: IEditorInput | undefined | null, options: IResourceOptions & { supportSideBySide?: SideBySideEditor.PRIMARY | SideBySideEditor.SECONDARY }): URI | undefined;
export function getOriginalUri(editor: IEditorInput | undefined | null, options: IResourceOptions & { supportSideBySide: SideBySideEditor.BOTH }): URI | { primary?: URI, secondary?: URI } | undefined;
export function getOriginalUri(editor: IEditorInput | undefined | null, options?: IResourceOptions): URI | { primary?: URI, secondary?: URI } | undefined {

    // What I would like to type:
    // return toResource(editor, options);

    // What I have to type
    if (!editor) {
        return undefined;
    }

    if (!options) {
        return toResource(editor);
    }

    if (options.supportSideBySide === SideBySideEditor.BOTH) {
        return toResource(editor, options);
    }

    if (options.supportSideBySide === SideBySideEditor.PRIMARY || options.supportSideBySide === SideBySideEditor.SECONDARY) {
        return toResource(editor, options);
    }
}

Expected behavior:
I can call the one method with overloads from the other without having to do a lot of checks.

Actual behavior:
I am often running into a problem when dealing with methods that define different overloads based on the types passed in. This works great if the method is called from the outside, but if internally I split the method up into 2 (as in the example above) I fail to call the one from the other somehow. I need to either duplicate all the code or do a lot of type checks in the second method that I will have to do again in the first method.

If there is guidelines how to do this any better, that would also help me.

Playground Link: Playground

Metadata

Metadata

Assignees

No one assigned

    Labels

    Design LimitationConstraints of the existing architecture prevent this from being fixed

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions