{"id":12611,"library":"vue-ts-types","title":"Vue TypeScript Prop Type Definitions","description":"vue-ts-types is a lightweight, TypeScript-first library designed to simplify and enhance the definition of Vue.js component props. It provides a fluent API for declaring prop types, addressing common pain points such as verbose prop declarations (especially when using Vue's built-in PropType utility), error-prone optional complex prop annotations (e.g., forgetting to union with `| undefined`), contradictions between `required` and `default` properties which lead to ambiguous behavior and ESLint warnings, and the inability to provide helpful custom validation error messages beyond a boolean result. The library is currently at version 1.9.0 and maintains an active release cadence with frequent minor updates. It supports both Vue 2.6+ and Vue 3.2+, shipping with full TypeScript type definitions. Since v1.9.0, it provides dual CommonJS and ES Module support, ensuring broad compatibility. Its core value lies in making prop definitions significantly more concise, type-safe, and less prone to common development errors in Vue projects utilizing TypeScript.","status":"active","version":"1.9.0","language":"javascript","source_language":"en","source_url":"https://github.com/FloEdelmann/vue-ts-types","tags":["javascript","vue","vue2","vue3","vuejs","vuejs2","vuejs3","typescript","prop-types"],"install":[{"cmd":"npm install vue-ts-types","lang":"bash","label":"npm"},{"cmd":"yarn add vue-ts-types","lang":"bash","label":"yarn"},{"cmd":"pnpm add vue-ts-types","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"`vue-ts-types` integrates directly with Vue.js's prop system and requires Vue to be present as a peer dependency.","package":"vue","optional":false}],"imports":[{"note":"Use named imports for individual prop type functions. Since v1.9.0, both ESM and CJS builds are provided, but named imports are generally preferred for tree-shaking in modern bundlers.","wrong":"const stringProp = require('vue-ts-types').stringProp","symbol":"stringProp","correct":"import { stringProp } from 'vue-ts-types'"},{"note":"All prop type definitions are available as named exports directly from the main package entry point. Avoid importing from internal paths, as these are not considered part of the public API and may change.","wrong":"import { oneOfProp as customOneOfProp } from 'vue-ts-types/dist/oneOfProp'","symbol":"oneOfProp","correct":"import { oneOfProp } from 'vue-ts-types'"},{"note":"Validator functions like `isPositive` are also named exports. Ensure your project is configured to handle ESM imports correctly if targeting an environment that doesn't support CJS by default (e.g., modern Node.js or browser builds).","wrong":"const isPositive = require('vue-ts-types').isPositive","symbol":"isPositive","correct":"import { isPositive } from 'vue-ts-types'"}],"quickstart":{"code":"import { defineComponent, createApp } from 'vue';\nimport {\n  arrayProp,\n  booleanProp,\n  functionProp,\n  isPositive,\n  numberProp,\n  oneOfProp,\n  stringProp\n} from 'vue-ts-types';\n\nconst MyComponent = defineComponent({\n  props: {\n    disabled: booleanProp().withDefault(false),\n    // resulting prop type: boolean\n\n    title: stringProp().optional,\n    // resulting prop type: string | undefined\n\n    description: stringProp().nullable,\n    // resulting prop type: string | null\n\n    items: arrayProp<string>().required,\n    // resulting prop type: string[]\n\n    callback: functionProp<() => void>().optional,\n    // resulting prop type: (() => void) | undefined\n\n    color: oneOfProp(['red', 'green', 'blue'] as const).withDefault('red'),\n    // resulting prop type: 'red' | 'green' | 'blue'\n\n    timeout: numberProp(isPositive).required,\n    // resulting prop type: number\n  },\n  template: `\n    <div>\n      <h1 v-if=\"title\">{{ title }}</h1>\n      <p v-if=\"description\">{{ description }}</p>\n      <button :disabled=\"disabled\" @click=\"callback\">Click Me</button>\n      <ul>\n        <li v-for=\"item in items\" :key=\"item\">{{ item }}</li>\n      </ul>\n      <p>Selected color: {{ color }}</p>\n      <p>Timeout (ms): {{ timeout }}</p>\n    </div>\n  `,\n  setup(props) {\n    // console.log(props.timeout);\n    return { };\n  }\n});\n\n// To run this in a browser, you would typically mount it:\n// const app = createApp(MyComponent);\n// app.mount('#app');\n\n// Example usage if you were creating a root app:\nconst app = createApp({\n  components: { MyComponent },\n  template: `<MyComponent title=\"Hello Vue Props\" :items=\"['Apple', 'Banana']\" :timeout=\"100\" />`\n});\n\n// In a real application, you'd mount this to an element in your HTML\n// app.mount('#app'); // Assuming you have <div id=\"app\"></div> in your HTML","lang":"typescript","description":"This example demonstrates how to define various component props using `vue-ts-types`, including optional, nullable, required, and validated props, showcasing type inference, default values, and how a component using these props might be defined and instantiated."},"warnings":[{"fix":"If encountering module resolution errors, upgrade to v1.7.1 or higher. For v1.9.0 and later, review your `tsconfig.json`'s `moduleResolution` and your bundler's configuration to correctly handle dual package exports, typically preferring ESM where supported.","message":"Version 1.7.0 mistakenly switched the package to ES Modules (ESM) only, causing immediate breaking changes for existing CommonJS (CJS) users. This was swiftly reverted in v1.7.1, but highlights potential module resolution issues. Since v1.9.0, dual ESM and CJS builds are officially provided, but careful configuration of your build tooling (e.g., Webpack, Rollup, Vite) is crucial to ensure it picks the correct module format for your target environment.","severity":"breaking","affected_versions":"1.7.0"},{"fix":"When using `vue-ts-types`, strictly choose between `.required` (for truly mandatory props with no default) or `.withDefault(value)` (for optional props that provide a fallback). The library's API prevents you from combining these conflicting modifiers, guiding you towards correct prop definitions.","message":"Attempting to combine `required: true` with a `default` value in standard Vue prop definitions is contradictory. Vue implicitly treats any prop with a `default` as optional, regardless of the `required` flag, leading to unexpected behavior and often triggering the `vue/no-required-prop-with-default` ESLint rule. `vue-ts-types` is designed to prevent this logical conflict.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Leverage `vue-ts-types`'s `.optional` or `.nullable` modifiers (e.g., `objectProp<MyType>().optional` or `stringProp().nullable`). These methods automatically infer and apply the correct `| undefined` or `| null` union type, ensuring your component's props are type-safe without manual `PropType` casting.","message":"A common TypeScript footgun in Vue is failing to explicitly union `PropType` with `undefined` or `null` for optional or nullable complex props (e.g., `PropType<MyType>` instead of `PropType<MyType | undefined>`). This results in incorrect type inference, leading to TypeScript errors when the prop might legitimately be absent or null.","severity":"gotcha","affected_versions":">=1.0.0"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"For projects using modern tooling, ensure your `tsconfig.json`'s `moduleResolution` (e.g., set to 'Bundler' or 'NodeNext') and your bundler's configuration (e.g., Webpack, Rollup, Vite) are set up to correctly resolve ES Modules. If explicitly targeting CommonJS, ensure your build picks up the CJS bundle; since v1.9.0, both are provided via the `exports` map in `package.json`.","cause":"This error typically occurs when a CommonJS-based environment or build setup attempts to import `vue-ts-types` as an ES Module, or if your tooling is not correctly configured to resolve dual packages.","error":"Module parse failed: Unexpected token 'export' (at line X, column Y) You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/configuration/module/#rule-type"},{"fix":"When using `vue-ts-types`, you should explicitly choose either the `.required` chainable method (for props that must always be provided) or the `.withDefault(value)` method (for optional props with a fallback). The library's API design prevents you from making this contradictory declaration.","cause":"This ESLint error, part of `eslint-plugin-vue`, indicates that a Vue prop has been declared as both `required: true` and includes a `default` value. This is a logical contradiction, as a default value inherently makes a prop optional.","error":"[vue/no-required-prop-with-default] The 'required' prop 'X' should not have a default value."},{"fix":"Verify that the generic type argument provided to functions like `arrayProp<T>()`, `objectProp<T>()`, or `functionProp<T>()` precisely matches the intended data structure. For props that are optional at runtime, ensure you use the `.optional` or `.nullable` modifiers (e.g., `stringProp().optional`) to correctly infer the `T | undefined` or `T | null` type, thus satisfying TypeScript's strict type checking.","cause":"This TypeScript error often points to a mismatch between the expected prop type and the provided type. It can occur if the generic type argument passed to `vue-ts-types` helpers is incorrect, or if an optional prop is not correctly typed to include `undefined`.","error":"Type 'X' is not assignable to type 'PropType<Y>'. Property 'Z' is missing in type 'X' but required in type 'Y'."}],"ecosystem":"npm"}