vuejs / vue-class-component

ES / TypeScript decorator for class-style Vue components.
MIT License
5.81k stars 429 forks source link

"Property '$refs' will overwrite the base property in 'Vue<unknown, {}, {}>'." in v8 #547

Closed YanDevDe closed 3 years ago

YanDevDe commented 3 years ago

Hello everyone!

I was trying to use $refs in App.vue under vue-class-component 8.0.0-rc1 with TypeScript, but for some reason, using this inside of class

import { Options, Vue } from "vue-class-component";
import MenuItem from "@/components/elements/MenuItem.vue"; // @ is an alias to /src

@Options({
  components: {
    MenuItem,
  },
})
export default class Home extends Vue {
  $refs!: {
    nav: HTMLElement
  }
}

caused following error:

ERROR in src/App.vue:49:3
TS2612: Property '$refs' will overwrite the base property in 'Vue<unknown, {}, {}>'. If this is intentional, add an initializer. Otherwise, add a 'declare' modifier or remove the redundant declaration.
    47 |   private resize_timer: any = null;
    48 |
  > 49 |   $refs!: {
       |   ^^^^^
    50 |     nav: HTMLElement
    51 |   }
    52 |

I'm using Vue 3.1.4 (per vue-cli), my tsconfig.json is:

{
  "compilerOptions": {
    "target": "esnext",
    "module": "esnext",
    "strict": true,
    "jsx": "preserve",
    "importHelpers": true,
    "moduleResolution": "node",
    "experimentalDecorators": true,
    "useDefineForClassFields": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "sourceMap": true,
    "baseUrl": ".",
    "types": [
      "webpack-env",
      "mocha",
      "chai"
    ],
    "paths": {
      "@/*": [
        "src/*"
      ]
    },
    "lib": [
      "esnext",
      "dom",
      "dom.iterable",
      "scripthost"
    ]
  },
  "include": [
    "src/**/*.ts",
    "src/**/*.tsx",
    "src/**/*.vue",
    "tests/**/*.ts",
    "tests/**/*.tsx"
  ],
  "exclude": [
    "node_modules"
  ]
}

Am I doing something wrong here?

Wish you a great day!

Yan

nick-ma commented 3 years ago

Use a declare in front of $refs will solve your problem.

<script lang="ts">
import { Vue, Options } from 'vue-class-component';
@Options({
  components: {},
})
export default class LoginPage extends Vue {
  // annotate refs type.
  declare $refs: {
    input: HTMLInputElement;
  };
  mounted() {
    // Use `input` ref without type cast.
    this.$refs.input.focus();
  }
}
</script>
YanDevDe commented 3 years ago

That worked out! Thank you so much @nick-ma :)