Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(menu): idea to introduce generics and better types for components #7114

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 15 additions & 1 deletion .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -95,5 +95,19 @@ module.exports = {
{ blankLine: 'always', prev: '*', next: 'block-like' },
{ blankLine: 'always', prev: ['import'], next: ['const', 'let', 'var'] }
]
}
},
overrides: [
{
files: ['*.typedef.vue'],
extends: ['plugin:vue/vue3-recommended', '@vue/eslint-config-typescript', 'plugin:@typescript-eslint/recommended-type-checked'],
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably no need for these plugins.

parser: 'vue-eslint-parser',
parserOptions: {
ecmaVersion: 'latest',
sourceType: 'module',
parser: '@typescript-eslint/parser',
project: ['tsconfig.lint.json'],
extraFileExtensions: ['.vue']
}
}
]
};
20 changes: 10 additions & 10 deletions packages/primevue/src/menu/Menu.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
* @module menu
*
*/
import type { DefineComponent, DesignToken, EmitFn, HintedString, PassThrough } from '@primevue/core';
import type { DesignToken, EmitFn, HintedString, PassThrough } from '@primevue/core';
import type { ComponentHooks } from '@primevue/core/basecomponent';
import type { MenuItem } from 'primevue/menuitem';
import type { PassThroughOptions } from 'primevue/passthrough';
Expand Down Expand Up @@ -191,11 +191,11 @@ export interface MenuRouterBindProps {
/**
* Defines valid properties in Menu component.
*/
export interface MenuProps {
export interface MenuProps<Item extends MenuItem = MenuItem> {
/**
* An array of menuitems.
*/
model?: MenuItem[] | undefined;
model?: Item[] | undefined;
/**
* Defines if menu would displayed as a popup.
* @defaultValue false
Expand Down Expand Up @@ -252,7 +252,7 @@ export interface MenuProps {
/**
* Defines valid slots in Menu component.
*/
export interface MenuSlots {
export interface MenuSlots<Item extends MenuItem = MenuItem> {
/**
* Custom start template.
*/
Expand All @@ -269,7 +269,7 @@ export interface MenuSlots {
/**
* Menuitem instance
*/
item: MenuItem;
item: Item;
/**
* Label property of the menuitem
*/
Expand All @@ -287,7 +287,7 @@ export interface MenuSlots {
/**
* Menuitem instance
*/
item: MenuItem;
item: Item;
/**
* Style class of the item icon element.
*/
Expand All @@ -302,7 +302,7 @@ export interface MenuSlots {
/**
* Menuitem instance
*/
item: MenuItem;
item: Item;
}): VNode[];
/**
* Custom submenu item template.
Expand All @@ -312,7 +312,7 @@ export interface MenuSlots {
/**
* Menuitem instance
*/
item: MenuItem;
item: Item;
}): VNode[];
}

Expand Down Expand Up @@ -370,11 +370,11 @@ export interface MenuMethods {
* @group Component
*
*/
declare const Menu: DefineComponent<MenuProps, MenuSlots, MenuEmits, MenuMethods>;
declare const Menu: typeof import('./Menu.typedef.vue')['default'];

declare module 'vue' {
export interface GlobalComponents {
Menu: DefineComponent<MenuProps, MenuSlots, MenuEmits, MenuMethods>;
Menu: typeof import('./Menu.typedef.vue')['default'];
}
}

Expand Down
16 changes: 16 additions & 0 deletions packages/primevue/src/menu/Menu.ts-playground.typedef.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<template>
<Menu :model="model">
<!-- We can safely access additional keys on the object instead of it acting as any. -->
<template #item="{ item }">{{ item.additionalData }}</template>
</Menu>
</template>

<script setup lang="ts">
import { MenuItem } from 'primevue/menuitem/MenuItem';

const model: (MenuItem & { additionalData: Record<string, number> })[] = [
{
additionalData: {}
}
];
</script>
9 changes: 9 additions & 0 deletions packages/primevue/src/menu/Menu.typedef.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<script setup lang="ts" generic="Item extends MenuItem">
import type { MenuItem } from 'primevue/menuitem';
import { MenuEmits, MenuMethods, MenuProps, MenuSlots } from './Menu';

defineProps<MenuProps<Item>>();
defineSlots<MenuSlots<Item>>();
defineEmits<MenuEmits>();
defineExpose<MenuMethods>();
</script>
2 changes: 1 addition & 1 deletion packages/primevue/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,6 @@
"@primevue/icons/*": ["../../packages/icons/src/*"]
}
},
"include": ["**/*.ts", "src/*"],
"include": ["**/*.ts", "src/*", "**/*.typedef.vue"],
"exclude": ["node_modules", "dist"]
}
Loading