Setting a default value for a complex prop in Vue through Type-based props declarations

I'm struggling with this issue:

Argument of type 'HelloWorldProps' is not assignable to parameter of type 'InferDefaults<LooseRequired<HelloWorldProps>>'.
  Types of property 'complexProp' are incompatible.ts(2345)

Here's the code snippet:

<script lang="ts">
export type ComplextPropType = boolean | string | any[] | null;

export interface HelloWorldProps {
  simpleProp?: boolean;
  complexProp: ComplextPropType;
  labels?: string[] // Vue docs example
}

export const HelloWorldPropsDefaults: HelloWorldProps = {
  simpleProp: false,
  complexProp: ((): ComplextPropType => null)(),
  //complexProp: ((): ComplextPropType => null),
  //complexProp: null,
  //labels: ()=> ['a', 'b'] // Vue docs mention something like this
};
</script>
<script setup lang="ts">
const props = withDefaults(
  defineProps<HelloWorldProps>(),
  HelloWorldPropsDefaults, // <-- Error reported here
);
</script>
<template>
  <h1>{{ props.complexProp }}</h1>
</template>

Any suggestions on how I can set a default value for complexProp?

Answer №1

For optimal readability and clarity, it is recommended to provide default values inline:

const props = withDefaults(
  defineProps<HelloWorldProps>(),
   {
     simpleProp: false,
     complexProp: ()=>[],
   }
);

If you prefer to separate them, consider defining type utilities similar to those found in the Vue runtime core:

<script lang="ts">
// These utilities can be stored in a separate file for reusability
type NotUndefined<T> = T extends undefined ? never : T

export type NativeType = null | number | string | boolean | symbol

type InferDefault<P, T> =

    ((props: P) => T & {}) | (T extends NativeType ? T : never) | (T extends (...args: any[]) => any ? T : never)

export type InferDefaults<T> = {
    [K in keyof T]?: InferDefault<T, T[K]>
}

export type ComplextPropType = boolean | string | any[] | null;

export interface HelloWorldProps {
  simpleProp?: boolean;
  complexProp: ComplextPropType;
  labels?: string[]
}

export const HelloWorldPropsDefaults: InferDefaults<HelloWorldProps> = {
  simpleProp: false,
  complexProp: ()=>[],
};

</script>

<script setup lang="ts">
const props = withDefaults(
  defineProps<HelloWorldProps>(),
  HelloWorldPropsDefaults, 
);
</script>
<template>
  <h1>{{ props.complexProp }}</h1>
</template>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

TypeScript's type assertions do not result in errors when provided with an incorrect value

We are currently using the msal library and are in the process of converting our javaScript code to TypeScript. In the screenshot below, TypeScript correctly identifies the expected type for cacheLocation, which can be either the string localStorage, the ...

The functionality of the Bootstrap Vue Tab component is experiencing issues when attempting to navigate tabs using an Index

Why doesn't this straightforward bootstrap vue script work? When the toggle button is pressed, the tabIndex value does not increment. The tabIndex initially set to 0. Even after pressing the button, the value remains at 0. If the tabIndex is rem ...

What sets apart window.location.href from this.router.url?

I'm curious about the various methods of obtaining the current URL in Angular. For instance: this.router.url My main question is: What advantages does using this.router.url offer over simply using window.location? Could someone kindly provide an exp ...

Bidirectional data binding using :model.sync when property includes both getter and setter functions

I have an input field with a dynamic value bound to it using v-model. To ensure reactivity, I have set up a computed property that triggers my Vuex action setText, which can then be accessed through the getter text. Here is how it is implemented: text: { ...

What is the method for including a dynamic image within the 'startAdornment' of MUI's Autocomplete component?

I'm currently utilizing MUI's autocomplete component to showcase some of my objects as recommendations. Everything is functioning correctly, however, I am attempting to include an avatar as a start adornment within the textfield (inside renderInp ...

Having trouble with gsap.reverse() not functioning properly when using onMouseLeave event in React

I've been incorporating simple gsap animations into my React application. I have successfully triggered an animation.play() function on onMouseEnter, but for some reason, the animation.reverse() function is not functioning as expected. Here's ho ...

Leveraging Promise in conjunction with async/await

As I venture into the world of async/await in TypeScript, I find myself pondering a few questions. Specifically, I have been working on a function to extract an ArrayBuffer from a Blob. async function readAsArrayBuffer(blob: Blob): Promise<ArrayBuffer& ...

Displaying Vue.js tooltips in a table when the text gets clipped

I'm currently facing an issue with creating a tooltip in my vue.js document. I attempted to follow this guide from https://www.w3schools.com/howto/tryit.asp?filename=tryhow_css_tooltip in order to create one, but it's not working as expected. Her ...

Tips for managing update logic in the server side with sveltekit

Currently, I am using Sveltekit and I am facing a dilemma regarding updating input data. The actual update process is straightforward, but there is an issue that arises when trying to send an update API request immediately, as it requires an accessToken to ...

The properties are not found in the type 'Observable<Todo[]>'

I'm currently following a YouTube tutorial and I've hit a roadblock trying to figure out where the error is originating from? Error Message: Type 'Observable' is missing properties such as length, pop, push, concat, and 25 more.ts(2740 ...

Obtain the appropriate selection in the dropdown based on the model in Angular

I am working on a dropdown menu that contains numbers ranging from 1 to 10. Below is the HTML code for it: <div class="form-group"> <label>{{l("RoomNumber")}}</label> <p-dropdown [disab ...

Extracting an array from an HTTP response in Angular/Typescript using the map operator or retrieving a specific element

Q1: How can I extract an array of objects from a http response using map in Angular? Q2: Is there a way to retrieve a specific object from a http response by utilizing map in Angular? Below are the example URL, sample data, CurrencyAPIResponse, and Curre ...

I am looking to transfer information from Angular 4 to Java servlet (cross-domain)

Having trouble sending data from Angular 4 to a Java servlet due to access control restrictions. Need to figure out how to properly insert data into the database using the Java servlet. Here is my code snippet: import { Injectable } from '@angular/ ...

Flatten information from an object containing multiple objects within an array

In my current project using Vue, I am making an API call to retrieve data from my Laravel backend (nova). The returned data is structured in the following way. The data consists of an array, which contains arrays of objects. Each array represents a record ...

Angular 2 code test coverage

Looking to calculate the code coverage of my Angular 2 code. Wondering if there are any plugins available for VS Code or WebStorm that can assist with this. My unit testing is done using Jasmine and Karma. ...

What are the steps to configure Bootstrap for optimal performance?

Here is the code snippet: <template lang="pug"> b-container b-row b-col h1 strong LICOTA® — ПРОФЕССИОНАЛЬНЫЙ ИНСТРУМЕНТ ВЫСШЕГО КЛАССА ДЛЯ АВТОСЕРВИСОВ И ПРОМ ...

New to React and struggling with updating the DOM

Upon receiving a React project, I am faced with the task of performing a complex state update on my DOM. Here is how my component looks: /** @jsx jsx */ import { jsx } from '@emotion/core'; import { Typography } from '@material-ui/core&ap ...

Exploring the methods for interpreting a JSON object within a Vue.js framework

Here is the json object I am working with: const faqs = [{'question1':'answer1'},{'question2':'answer2'}] In my Vue.js code, I am attempting to iterate through this data using a for loop within a div like so: <di ...

Having trouble with routerLink in your custom library while using Angular 4?

In my Angular 4 project, I have developed a custom sidebar library and integrated it into the main project. My current issue is that I want to provide the option for users to "open in new tab/window" from the browser's context menu without having the ...

What is the best way to incorporate additional data into a TypeScript object that is structured as JSON?

I'm exploring ways to add more elements to an object, but I'm uncertain about the process. My attempts to push data into the object have been unsuccessful. people = [{ name: 'robert', year: 1993 }]; //I aim to achieve this peopl ...