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

Vuejs type inference does not work with TS 3.4.x #9873

Open
Patcher56 opened this Issue Apr 15, 2019 · 10 comments

Comments

Projects
None yet
7 participants
@Patcher56
Copy link

Patcher56 commented Apr 15, 2019

Version

2.6.10

Reproduction link

https://github.com/Patcher56/ts3.4.x-vuejs-issue

Steps to reproduce

  1. create a new vue typescript project (without class syntax) vue create test-ts
  2. open src/components/HelloWorld.vue
  3. add a data variable and try to access it in a computed property

What is expected?

No errors (as the data is defined)

What is actually happening?

Typescript error 2339 telling me
Property 'test' does not exist on type 'CombinedVueInstance<Vue, {}, {}, {}, Readonly<{ msg: string; }>>'.

image


I think this has something to do with the changed type inference in Typescript 3.4.x.

Important: Change vetur settings to use workspace dependencies to show errors directly in vscode, else you will only get the error when using yarn serve.

@LinusBorg

This comment has been minimized.

Copy link
Member

LinusBorg commented Apr 15, 2019

Seems to belong into the vetur repository then, right?

@Patcher56

This comment has been minimized.

Copy link
Author

Patcher56 commented Apr 15, 2019

No, because the errors also appear in the terminal when using yarn serve.
Vetur is just responsible for showing me the errors directly in vscode.

patrick@patrick-Ubuntu:~/dev/test/test$ yarn serve
yarn run v1.15.2
$ vue-cli-service serve
 INFO  Starting development server...
Starting type checking service...
Using 1 worker with 2048MB memory limit
 98% after emitting CopyPlugin                                                 

 DONE  Compiled successfully in 2925ms                                                                                                                                        09:12:39

Type checking in progress...

  App running at:
  - Local:   http://localhost:8081/ 
  - Network: http://10.25.1.148:8081/

  Note that the development build is not optimized.
  To create a production build, run yarn build.

ERROR in /home/patrick/dev/test/test/src/components/HelloWorld.vue
104:19 Property 'test' does not exist on type 'CombinedVueInstance<Vue, {}, {}, {}, Readonly<{ msg: string; }>>'.
    102 |   computed: {
    103 |     testComp: function() {
  > 104 |       return this.test === false;
        |                   ^
    105 |     }
    106 |   }
    107 | });
Version: typescript 3.4.3
Time: 3161ms
@yyx990803

This comment has been minimized.

Copy link
Member

yyx990803 commented Apr 15, 2019

@HerringtonDarkholme

This comment has been minimized.

Copy link
Member

HerringtonDarkholme commented Apr 15, 2019

Looks like TS3.4 has multiple inference issue...

The minimal repro:

Vue.component('test', {
  data() {
    return {
      test: 123
    }
  },
  computed: {
    ttt() {
      return this.test + 1
    }
  },
})

Also spotted another failure:

The catch-all type signature of component

  component(id: string, definition?: ComponentOptions<V>): ExtendedVue<V, {}, {}, {}, {}>;

is causing union type to fail checking.

I need more time for investigation...

@DaKoala

This comment has been minimized.

Copy link
Contributor

DaKoala commented Apr 15, 2019

I wonder if properties in data are supposed to become properties of the instance when using TypeScript?

@LinusBorg

This comment has been minimized.

Copy link
Member

LinusBorg commented Apr 15, 2019

Of course...

@mrozekma

This comment has been minimized.

Copy link

mrozekma commented Apr 15, 2019

I filed the same bug against Typescript (Microsoft/TypeScript#30854)

@HerringtonDarkholme

This comment has been minimized.

Copy link
Member

HerringtonDarkholme commented Apr 16, 2019

Minimal repro:

type TypedDef<Data, Computed> =
  ComponentOptions<Data, Computed> &
  ThisType<Data & Computed>

type DataDef<Data> = () => Data

export interface ComponentOptions<Data, Computed> {
  data?: DataDef<Data>
  computed?: Accessors<Computed>
}
export type Accessors<T> = {
  [K in keyof T]: () => T[K]
}

declare function component<Data, Computed>(def: TypedDef<Data, Computed>): void;

component({
  data() {
    return {
      foo: 23
    }
  },
  computed: {
    bar() {
      // return this.foo + 1 // comment out the return solves the problem
    }
  }
})

The problem seems to be cyclic inference issue. If the computed property doesn't reference data, the compiler error goes away.

I think it should goes to TypeScript's repo.

@pikax

This comment has been minimized.

Copy link
Contributor

pikax commented Apr 16, 2019

One workaround is assigning a return type to computed

type TypedDef<Data, Computed> =
  ComponentOptions<Data, Computed> &
  ThisType<Data & Computed>

type DataDef<Data> = () => Data

export interface ComponentOptions<Data, Computed> {
  data?: DataDef<Data>
  computed?: Accessors<Computed>
}
export type Accessors<T> = {
  [K in keyof T]: () => T[K]
}

declare function component<Data, Computed>(def: TypedDef<Data, Computed>): void;

component({
  data() {
    return {
      foo: 23
    }
  },
  computed: {
    bar(): number { // adding the return type, seems to solve the error
      return this.foo + 1
    }
  }
})
@mrozekma

This comment has been minimized.

Copy link

mrozekma commented Apr 16, 2019

One workaround is assigning a return type to computed

Good call. Just discovered that workaround is documented here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.