-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Description
Describe the bug
DataTable's v-model:filters and DatePicker's v-model lose type specificity through DefineComponent's no-arg constructor. The emit callback always uses the widest union type instead of the consumer's specific type.
For example, v-model:filters on DataTable emits DataTableFilterMeta (index signature type) back to the consumer's specific typed object { global: ...; id: ...; }, which TypeScript rejects with strictTemplates: true.
This is the same root cause as #7426 — PR #7427 made DataTableProps<T> generic, but the component declaration still uses DefineComponent with new (), so TypeScript cannot infer T (or any other generic) from template bindings.
Root cause: PrimeVue's DefineComponent uses new () (no-arg constructor). vue-tsc generates new Component({...props...}) in template codegen, but with a no-arg constructor, InstanceType<T> erases generic parameters to defaults. When the constructor accepts props (new (props: P)), TypeScript infers generics from the actual prop values automatically.
PrimeVue version
4.5.4
Vue version
3.5.x
Language
TypeScript
Build / Runtime
Vite
Steps to reproduce the behavior
- Enable
strictTemplates: trueintsconfig.jsonundervueCompilerOptions - Create a typed filter object:
const filters = ref<{ global: DataTableFilterMetaData; id: DataTableFilterMetaData }>({...}) - Use
<DataTable v-model:filters="filters"> - Run
vue-tsc --noEmit - Observe:
Type 'DataTableFilterMeta' is missing the following properties from type '{ global: ...; id: ...; }'
Expected behavior
No type error — v-model:filters should infer the filter type from the bound ref and emit the same type back.