Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Type of generic function parameter not being inferred from interface generic type. #30505

Closed
pikax opened this issue Mar 20, 2019 · 2 comments · Fixed by #31221
Closed

Type of generic function parameter not being inferred from interface generic type. #30505

pikax opened this issue Mar 20, 2019 · 2 comments · Fixed by #31221
Assignees
Labels
Bug A bug in TypeScript Fixed A PR has been merged for this issue

Comments

@pikax
Copy link

pikax commented Mar 20, 2019

TypeScript Version: 3.4.0@rc

Search Terms:

Code

export type Prop<T> = { (): T }
export type PropType<T> = Prop<T>;
export type PropDefaultValue<T> = T;


export type PropValidatorFunction<T> = (value: T) => boolean;
export type PropValidator<T> = PropOptions<T>;


export type PropOptions<T> = {
    type: PropType<T>;

    value?: PropDefaultValue<T>,
    required?: boolean;
    validator?: PropValidatorFunction<T>;
}

export type RecordPropsDefinition<T> = {
    [K in keyof T]: PropValidator<T[K]>
}
export type PropsDefinition<T> = RecordPropsDefinition<T>;


declare function extend<T>({ props }: { props: PropsDefinition<T> }):  PropsDefinition<T>;

interface MyType {
    valid: boolean;
}

const r = extend({
    props: {
        // gets resolved to PropOptions<any> but should be PropType<MyType>
        notResolved: {
            type: Object as PropType<MyType>,

            // type not inferred 
            validator: (x) => {
                return x.valid;
            }
        },
        // gets resolved currectly to PropType<MyType>
        // on typescript@3.4rc doest resolve to PropType<MyType>
        explicit: {
            type: Object as PropType<MyType>,

            // type not inferred 
            validator: (x: MyType) => {
                return x.valid;
            }
        }
    }
})

// return type on 3.4@rc doesn't get resolved
r.explicit
r.notResolved
r.explicit.required
r.notResolved.required

Expected behavior:
The validator parameter as typescript type inferred from T.
Props record values to be resolved with the interface of PropType
Return type to be PropsDefinition<T>

Actual behavior:
Getting validator parameter resolved as any/unknown.
Record types are not getting resolve to the type PropOptions<T> in 3.4@rc but working in 3.3.x
The return type not working in 3.4@rc

Playground Link:
playground

@RyanCavanaugh
Copy link
Member

This hasn't worked particularly well in any version, but this seems to be regressing:

type Box<T> = {
    contents: T;
    contains?(content: T): boolean;
};
type Mapped<T> = {
    [K in keyof T]: Box<T[K]>;
}
declare function id<T>(arg: Mapped<T>): Mapped<T>;

// obj1: Mapped<{ foo: string }> ✔
const obj1 = id({
    foo: {
        contents: ""
    }
});

// 3.3 obj2: Mapped<{ foo: any }> ❌
// 3.4 obj2: Mapped<{}> ❌❌
const obj2 = id({
    foo: {
        contents: "",
        // k: implicit any ❌
        contains(k) {
            return k.length > 0;
        }
    }
});

@RyanCavanaugh RyanCavanaugh added the Needs Investigation This issue needs a team member to investigate its status. label Mar 26, 2019
RyanCavanaugh added a commit to RyanCavanaugh/TypeScript that referenced this issue May 1, 2019
RyanCavanaugh added a commit that referenced this issue May 1, 2019
@ahejlsberg
Copy link
Member

The key issue here is that during the initial pass in type inference where we defer context sensitive function expressions and arrow functions, we never perform reverse mapped type inference on types that contain anything context sensitive. That is too conservative because, as illustrated by the examples, there are cases where we want to infer from the properties that aren't context sensitive and then apply those inferences to the context sensitive locations. I will be putting up a PR that does this.

@ahejlsberg ahejlsberg added Bug A bug in TypeScript and removed Needs Investigation This issue needs a team member to investigate its status. labels May 2, 2019
@ahejlsberg ahejlsberg added this to the TypeScript 3.5.0 milestone May 2, 2019
@ahejlsberg ahejlsberg added the Fixed A PR has been merged for this issue label May 2, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug A bug in TypeScript Fixed A PR has been merged for this issue
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants