Компонент Renderless Vue в TypeScript - PullRequest
2 голосов
/ 19 сентября 2019

У меня есть компонент без рендеринга в JavaScript, который я пытаюсь преобразовать в TypeScript.Я сталкиваюсь с ошибками, объявляя функцию render в компоненте Vue.extend:

(method) ComponentOptions<Vue, unknown, unknown, unknown, never[], Record<never, any>>.render?(createElement: CreateElement, hack: RenderContext<Record<never, any>>): VNode
  No overload matches this call.
  The last overload gave the following error.
  Argument of type '{ render(): void; }' is not assignable to parameter of type 'ComponentOptions<Vue, DefaultData<Vue>, DefaultMethods<Vue>, DefaultComputed, PropsDefinition<Record<string, any>>, Record<string, any>>'.
    Types of property 'render' are incompatible.
      Type '() => void' is not assignable to type '(createElement: CreateElement, hack: RenderContext<Record<string, any>>) => VNode'.
        Type 'void' is not assignable to type 'VNode'.ts(2769)
        vue.d.ts(90, 3): The last overload is declared here.

Это пример того, что я пытаюсь сделать в TypeScript:

import Vue from 'vue'

export default Vue.extend({
  render() { // error happens when I add this. I tried typing the render with :VNode
             // and returning this.$scopedSlots.default({}), but error still occurs
  }
})

Как мне это исправить?

1 Ответ

0 голосов
/ 22 сентября 2019

render() имеет эту подпись:

render?(createElement: CreateElement, hack: RenderContext<Props>): VNode;

Примечания для объявления render():

  • hack не требуется объявлятьв вашем коде
  • объявления аргументов не нужны в функции без визуализации
  • тип возвращаемого значения VNode (т. е. один корневой узел), но Vue фактически принимает VNode[] в качестве возврата (которыйэто то, что this.$scopedSlots.default() возвращает)

Решение 1: Укажите тип возвращаемого значения VNode и верните один узел, который переносит this.$scopedSlots.default():

import Vue, { VNode, CreateElement } from 'vue'

export default Vue.extend({
  render(h: CreateElement): VNode {
    return h('div', this.$scopedSlots.default!({}))
  }
})

Решение 2: Используйте any утверждение типа на this.$scopedSlots.default(), чтобы обойти ошибку типа:

import Vue from 'vue'

export default Vue.extend({
  render() {
    // The container node is expected to provide a single root,
    // so it's okay to return `VNode[]` as any.
    return this.$scopedSlots.default!({}) as any
  }
})
...