TypeScript

Vue Lynx supports TypeScript out of the box. Since Vue Lynx is built on the standard Vue 3 runtime, all of Vue's TypeScript features work as documented in the Vue TypeScript guide -- <script lang="ts">, defineComponent(), template type checking, and so on.

This page covers what's specific to Vue Lynx: type declarations for Lynx built-in elements and a Volar plugin for correct IDE resolution.

Prerequisite: Rspeedy TypeScript setup

Before configuring Vue Lynx types, make sure your project has the base Rspeedy TypeScript setup in place -- rspeedy-env.d.ts, path aliases, isolatedModules, etc. See the Rspeedy TypeScript guide for details.

Lynx Element Types

By default, Volar resolves tags like <view> and <text> as SVG elements, since they exist in the SVG spec. Vue Lynx provides type declarations that override this with Lynx-specific types, and a Volar plugin that tells the language server to treat them as custom components.

Add the following to your source-level tsconfig.json (typically src/tsconfig.json):

src/tsconfig.json
{
  "compilerOptions": {
    "types": ["vue-lynx/types"]
  },
  "vueCompilerOptions": {
    "plugins": ["vue-lynx/types/volar-plugin"]
  }
}
Tip

If you created your project with create-vue-lynx (TypeScript template), this is already configured.

What each option does:

  • "types": ["vue-lynx/types"] augments Vue's GlobalComponents interface with all Lynx built-in elements (view, text, image, scroll-view, list, etc.) and their typed props and events.
  • "plugins": ["vue-lynx/types/volar-plugin"] configures Volar's isNativeTag so that Lynx elements are resolved through the GlobalComponents augmentation instead of falling back to SVG definitions.

With this setup, your IDE will provide prop autocomplete, event autocomplete, and type errors for all Lynx elements.

Example

Here's a typical component using typed props with Lynx elements:

src/Greeting.vue
<script setup lang="ts">
defineProps<{
  name: string
  avatarUrl: string
}>()
</script>

<template>
  <view style="{ flexDirection: 'row', alignItems: 'center' }">
    <image :src="avatarUrl" style="{ width: 40, height: 40 }" />
    <text @tap="() => console.log('tapped')">Hello, {{ name }}</text>
  </view>
</template>

In this example, <view>, <image>, and <text> all have full IntelliSense -- src on <image> is typed as a string, @tap on <text> is recognized as a valid event, and misspelled props like <view srcc="..."> would produce a type error.

Event Types

Lynx uses the bind* convention for events (e.g., bindtap, bindtouchstart). The Vue Lynx type declarations automatically map these to Vue's on* convention:

LynxVue templateVue JSX
bindtap@taponTap
bindtouchstart@touchstartonTouchstart
bindlayoutchange@layoutchangeonLayoutchange

The mapping uses TypeScript's Capitalize utility type on the suffix after bind, so bindtouchstart becomes onTouchstart (not onTouchStart). All event handler types are preserved through the transformation, so you get full type checking on event callback parameters.

Type Checking

Following the same approach as standard Vue projects (see Vue docs on type checking), use vue-tsc for command-line type checking:

npx vue-tsc --noEmit

This validates your Lynx element usage, props, and events against the type declarations, including inside .vue single-file components.