Repository: Kong/kongponents
Pull request #2744: feat(ktoaster): precise typings for ktoaster
Author: login: TT1228
Labels: name: released
Created: 2025-05-09T03:53:42Z | Merged: 2025-05-16T16:20:36Z

# Summary

KM-1241



Diff:
diff --git a/src/components/KToaster/KToaster.vue b/src/components/KToaster/KToaster.vue
index 06055933be..9b3c8da534 100644
--- a/src/components/KToaster/KToaster.vue
+++ b/src/components/KToaster/KToaster.vue
@@ -38,7 +38,7 @@
         class="toaster-close-icon"
         data-testid="toaster-close-icon"
         type="button"
-        @click.stop="$emit('close', toaster.key)"
+        @click.stop="emit('close', toaster.key)"
       >
         <CloseIcon
           :color="`var(--kui-color-text-neutral-weak, ${KUI_COLOR_TEXT_NEUTRAL_WEAK})`"
@@ -50,28 +50,18 @@
 </template>
 
 <script lang="ts" setup>
-import type { PropType } from 'vue'
-import type { Toast, ToasterAppearance } from '@/types'
+import type { ToasterAppearance, ToasterProps, ToasterEmits } from '@/types'
 import { InfoIcon, CheckCircleIcon, WarningIcon, ClearIcon, KongIcon, CloseIcon } from '@kong/icons'
 import { KUI_COLOR_TEXT, KUI_COLOR_TEXT_NEUTRAL_WEAK, KUI_ICON_SIZE_50 } from '@kong/design-tokens'
 
 type ToastIcon = typeof InfoIcon | typeof CheckCircleIcon | typeof WarningIcon | typeof ClearIcon | typeof KongIcon
 
-defineProps({
-  toasterState: {
-    type: Array as PropType<Toast[]>,
-    default: [] as Toast[],
-    required: true,
-  },
-  zIndex: {
-    type: Number,
-    default: 10000,
-  },
-})
-
-defineEmits<{
-  (e: 'close', val: any): void
-}>()
+const {
+  toasterState = [],
+  zIndex = 10000,
+} = defineProps<ToasterProps>()
+
+const emit = defineEmits<ToasterEmits>()
 
 const getToastIcon = (appearance?: ToasterAppearance): ToastIcon => {
   switch (appearance) {
diff --git a/src/components/KToaster/ToastManager.ts b/src/components/KToaster/ToastManager.ts
index 94ee1e1e66..34aa7f12fb 100644
--- a/src/components/KToaster/ToastManager.ts
+++ b/src/components/KToaster/ToastManager.ts
@@ -34,7 +34,7 @@ export default class ToastManager {
     this.toaster = createVNode(KToaster, {
       toasterState: this.toasts.value,
       zIndex: options?.zIndex ? options.zIndex : defaultZIndex,
-      onClose: (key: any) => this.close(key),
+      onClose: (key: string) => this.close(key),
     })
 
     if (this.toastersContainer) {
@@ -42,7 +42,7 @@ export default class ToastManager {
     }
   }
 
-  setTimer(key: any, timeout: number): number {
+  setTimer(key: string, timeout: number): number {
     return setTimeout(() => this.close(key), timeout)
   }
 
@@ -67,7 +67,7 @@ export default class ToastManager {
     })
   }
 
-  close(key: any): void {
+  close(key: string): void {
     const i: number = this.toasts.value?.findIndex(n => key === n.key)
     clearTimeout(this.toasts.value[i]?.timer)
     this.toasts.value.splice(i, 1)
diff --git a/src/types/toaster.ts b/src/types/toaster.ts
index 72226969e8..57dc1ada60 100644
--- a/src/types/toaster.ts
+++ b/src/types/toaster.ts
@@ -2,14 +2,14 @@ export type ToasterAppearance = 'info' | 'success' | 'danger' | 'warning' | 'sys
 
 export interface Toast {
   /** Unique identifier of toaster */
-  key?: any
+  key: string
   /** Title of toaster */
   title?: string
   /** Text to display in toaster */
   message?: string
   appearance?: ToasterAppearance
   timeoutMilliseconds?: number
-  timer?: any
+  timer?: number
 }
 
 export type ToasterAppearancesRecord = Record<ToasterAppearance, ToasterAppearance>
@@ -24,3 +24,24 @@ export const ToasterAppearances: ToasterAppearancesRecord = {
 export interface ToasterOptions {
   zIndex?: number
 }
+
+export interface ToasterProps {
+  /**
+   * The toaster state.
+   * @default []
+   */
+  toasterState: Toast[]
+
+  /**
+   * The z-index of the toaster.
+   * @default 10000
+   */
+  zIndex?: number
+}
+
+export interface ToasterEmits {
+  /**
+   * Emitted when a toaster is closed.
+   */
+  close: [val: string]
+}


Reviews:
user: login: Justineo
state: CHANGES_REQUESTED
author_association: MEMBER
submitted_at: 2025-05-12T16:23:36Z
user: login: Justineo
state: APPROVED
author_association: MEMBER
submitted_at: 2025-05-16T15:09:09Z
user: login: adamdehaven
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-16T15:47:35Z
user: login: Justineo
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-16T16:01:09Z
user: login: adamdehaven
state: APPROVED
author_association: MEMBER
submitted_at: 2025-05-16T16:20:34Z

Review comments:
diff_hunk: @@ -50,28 +50,18 @@
 </template>
 
 <script lang="ts" setup>
-import type { PropType } from 'vue'
-import type { Toast, ToasterAppearance } from '@/types'
+import type { ToasterAppearance, ToasterProps, ToasterEmits } from '@/types'
 import { InfoIcon, CheckCircleIcon, WarningIcon, ClearIcon, KongIcon, CloseIcon } from '@kong/icons'
 import { KUI_COLOR_TEXT, KUI_COLOR_TEXT_NEUTRAL_WEAK, KUI_ICON_SIZE_50 } from '@kong/design-tokens'
 
 type ToastIcon = typeof InfoIcon | typeof CheckCircleIcon | typeof WarningIcon | typeof ClearIcon | typeof KongIcon
 
-defineProps({
-  toasterState: {
-    type: Array as PropType<Toast[]>,
-    default: [] as Toast[],
-    required: true,
-  },
-  zIndex: {
-    type: Number,
-    default: 10000,
-  },
-})
-
-defineEmits<{
-  (e: 'close', val: any): void
-}>()
+const {
+  toasterState = [],
+  zIndex = 10000,
+} = defineProps<ToasterProps>()
+
+defineEmits<ToasterEmits>()
path: src/components/KToaster/KToaster.vue
user: login: Justineo
body: Let's add `const emit = ...` and remove the usage of `$emit` from the template.
created_at: 2025-05-09T04:12:47Z
author_association: MEMBER
diff_hunk: @@ -34,15 +34,15 @@ export default class ToastManager {
     this.toaster = createVNode(KToaster, {
       toasterState: this.toasts.value,
       zIndex: options?.zIndex ? options.zIndex : defaultZIndex,
-      onClose: (key: any) => this.close(key),
+      onClose: (key: string) => this.close(key),
path: src/components/KToaster/ToastManager.ts
user: login: adamdehaven
body: question: the interface is changing here; is that going to create a downstream issue?
created_at: 2025-05-16T15:47:16Z
author_association: MEMBER
diff_hunk: @@ -34,15 +34,15 @@ export default class ToastManager {
     this.toaster = createVNode(KToaster, {
       toasterState: this.toasts.value,
       zIndex: options?.zIndex ? options.zIndex : defaultZIndex,
-      onClose: (key: any) => this.close(key),
+      onClose: (key: string) => this.close(key),
     })
 
     if (this.toastersContainer) {
       render(this.toaster, this.toastersContainer)
     }
   }
 
-  setTimer(key: any, timeout: number): number {
+  setTimer(key: string, timeout: number): number {
path: src/components/KToaster/ToastManager.ts
user: login: adamdehaven
body: question: the interface is changing here; is that going to create a downstream issue?
created_at: 2025-05-16T15:47:20Z
author_association: MEMBER
diff_hunk: @@ -67,7 +67,7 @@ export default class ToastManager {
     })
   }
 
-  close(key: any): void {
+  close(key: string): void {
path: src/components/KToaster/ToastManager.ts
user: login: adamdehaven
body: question: the interface is changing here; is that going to create a downstream issue?
created_at: 2025-05-16T15:47:23Z
author_association: MEMBER
diff_hunk: @@ -2,14 +2,14 @@ export type ToasterAppearance = 'info' | 'success' | 'danger' | 'warning' | 'sys
 
 export interface Toast {
   /** Unique identifier of toaster */
-  key?: any
+  key: string
path: src/types/toaster.ts
user: login: adamdehaven
body: question: the interface is changing here; is that going to create a downstream issue?
created_at: 2025-05-16T15:47:29Z
author_association: MEMBER
diff_hunk: @@ -2,14 +2,14 @@ export type ToasterAppearance = 'info' | 'success' | 'danger' | 'warning' | 'sys
 
 export interface Toast {
   /** Unique identifier of toaster */
-  key?: any
+  key: string
   /** Title of toaster */
   title?: string
   /** Text to display in toaster */
   message?: string
   appearance?: ToasterAppearance
   timeoutMilliseconds?: number
-  timer?: any
+  timer?: number
path: src/types/toaster.ts
user: login: adamdehaven
body: question: the interface is changing here; is that going to create a downstream issue?
created_at: 2025-05-16T15:47:32Z
author_association: MEMBER
diff_hunk: @@ -34,15 +34,15 @@ export default class ToastManager {
     this.toaster = createVNode(KToaster, {
       toasterState: this.toasts.value,
       zIndex: options?.zIndex ? options.zIndex : defaultZIndex,
-      onClose: (key: any) => this.close(key),
+      onClose: (key: string) => this.close(key),
path: src/components/KToaster/ToastManager.ts
user: login: Justineo
body: I believe the Konnect preview PR is good https://github.com/Kong/konnect-ui-apps/pull/6728 (but there are conflicts now).
created_at: 2025-05-16T16:01:09Z
author_association: MEMBER

PR comments:
user: login: netlify[bot]
created_at: 2025-05-09T03:53:47Z
body: ### <span aria-hidden="true">✅</span> Deploy Preview for *kongponents-sandbox* ready!


|  Name | Link |
|:-:|------------------------|
|<span aria-hidden="true">🔨</span> Latest commit | 6cfba8335e6a273de3d560eff788f322be8d36a8 |
|<span aria-hidden="true">🔍</span> Latest deploy log | https://app.netlify.com/sites/kongponents-sandbox/deploys/68242ad4f0b6540008a82707 |
|<span aria-hidden="true">😎</span> Deploy Preview | [https://deploy-preview-2744--kongponents-sandbox.netlify.app](https://deploy-preview-2744--kongponents-sandbox.netlify.app) |
|<span aria-hidden="true">📱</span> Preview on mobile | <details><summary> Toggle QR Code... </summary><br /><br />![QR Code](https://app.netlify.com/qr-code/eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1cmwiOiJodHRwczovL2RlcGxveS1wcmV2aWV3LTI3NDQtLWtvbmdwb25lbnRzLXNhbmRib3gubmV0bGlmeS5hcHAifQ.iDL986xzN7NtHs0wEMcHlI4vuDyd1EK6u_AOTv0Fl8o)<br /><br />_Use your smartphone camera to open QR code link._</details> |
---
<!-- [kongponents-sandbox Preview](https://deploy-preview-2744--kongponents-sandbox.netlify.app) -->
_To edit notification comments on pull requests, go to your [Netlify site configuration](https://app.netlify.com/sites/kongponents-sandbox/configuration/notifications#deploy-webhooks)._
author_association: NONE
user: login: netlify[bot]
created_at: 2025-05-09T03:55:08Z
body: ### <span aria-hidden="true">✅</span> Deploy Preview for *kongponents* ready!


|  Name | Link |
|:-:|------------------------|
|<span aria-hidden="true">🔨</span> Latest commit | 6cfba8335e6a273de3d560eff788f322be8d36a8 |
|<span aria-hidden="true">🔍</span> Latest deploy log | https://app.netlify.com/sites/kongponents/deploys/68242ad4e8fcb90008a1bf13 |
|<span aria-hidden="true">😎</span> Deploy Preview | [https://deploy-preview-2744--kongponents.netlify.app](https://deploy-preview-2744--kongponents.netlify.app) |
|<span aria-hidden="true">📱</span> Preview on mobile | <details><summary> Toggle QR Code... </summary><br /><br />![QR Code](https://app.netlify.com/qr-code/eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1cmwiOiJodHRwczovL2RlcGxveS1wcmV2aWV3LTI3NDQtLWtvbmdwb25lbnRzLm5ldGxpZnkuYXBwIn0.mpNlgWEy5DrPcYng7tNy4GzdASTQQZrrhJt1boVzuoM)<br /><br />_Use your smartphone camera to open QR code link._</details> |
---
<!-- [kongponents Preview](https://deploy-preview-2744--kongponents.netlify.app) -->
_To edit notification comments on pull requests, go to your [Netlify site configuration](https://app.netlify.com/sites/kongponents/configuration/notifications#deploy-webhooks)._
author_association: NONE
user: login: kongponents-bot
created_at: 2025-05-16T16:26:44Z
body: :tada: This PR is included in version 9.32.0 :tada:

The release is available on:
- [npm package (@latest dist-tag)](https://www.npmjs.com/package/@kong/kongponents/v/9.32.0)
- [GitHub release](https://github.com/Kong/kongponents/releases/tag/v9.32.0)

Your **[semantic-release](https://github.com/semantic-release/semantic-release)** bot :package::rocket:
author_association: COLLABORATOR
user: login: kongponents-bot
created_at: 2025-05-16T16:28:49Z
body: ## ***Preview*** package from this PR in consuming application
In consuming application project install preview version of kongponents generated by this PR:
```
@kong/kongponents@pr-2744
```
<!-- Sticky Pull Request Commentpr_preview_consumption -->
author_association: COLLABORATOR