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

TypeScript: can't infer prop names and types when contains any type prop #6841

Closed
wonderful-panda opened this Issue Oct 18, 2017 · 4 comments

Comments

Projects
None yet
5 participants
@wonderful-panda

wonderful-panda commented Oct 18, 2017

Version

2.5.2

Reproduction link

https://github.com/wonderful-panda/vue-sandbox

Steps to reproduce

Compile this code by tsc

import Vue, { VNode } from "vue";

const NgComponent = Vue.extend({
    name: "NgComponent",
    props: {
        foo: { type: String },
        bar: {}    // any types are accepted
    },
    render(h): VNode {
        return h("div", this.foo);
    }
});

or clone from repro link and npm install && npm run build

What is expected?

Successfully compiled.

And this.foo is treated as string, this.bar is treated as any.

What is actually happening?

Failed to compile.

src/index.ts(10,30): error TS2339: Property 'foo' does not exist on type 'CombinedVueInstance<Vue, {}, {}, {}, Readonly<{}>>'.

Workaround:

import Vue, { VNode } from "vue";

Vue.extend({
    name: "Workaround",
    props: {
        foo: { type: String },
        bar: {} as (() => any)   // any types are accepted
    },
    render(h): VNode {
        return h("div", this.foo);
    }
});
@ktsn

This comment has been minimized.

Member

ktsn commented Oct 19, 2017

Indeed it does not work if it has any typed props definition. I'm not sure about the reason, though.

@HerringtonDarkholme @DanielRosenwasser
I would appreciate if you can look into it.

@DanielRosenwasser

This comment has been minimized.

DanielRosenwasser commented Oct 19, 2017

I'm currently not by a computer but I'll guess a bit. Right now it's probably an assignability error for props in general, but we can do better there in future versions of TypeScript. I'm currently on a branch where this works better.

The thing is that even on this branch, the best inference I can get is {}.

@HerringtonDarkholme

This comment has been minimized.

Member

HerringtonDarkholme commented Oct 20, 2017

With #6850 , you can do this.

import Vue, { VNode } from "vue";

Vue.extend({
    name: "Workaround",
    props: {
        foo: { type: String },
        bar: {} as Prop<any>
    },
    render(h): VNode {
        return h("div", this.foo);
    }
});

I think inferring any from empty prop type is too lenient. A lot of options will have empty field, which results in empty type parameter. If we make inference default to any, there will be too many errors hidden by unintended any.

@yyx990803

This comment has been minimized.

Member

yyx990803 commented Nov 27, 2017

Closing this one - please keep an eye on #6856 (to be merged for 2.6)

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