So I'm new to Typescript and VueJS and all of its new features.
Everything works as it is supposed to be but I cannot get rid of my typescript error and using v-model at the same time.
I'm working on a webview for a member to check and change its attributes. I get my members data from an API and store it in a PiniaStore. This means I have several InputFields requiring numbers and strings for a member. AFAIK v-model is the way to go for InputFields.
Type 'string | number | null | undefined' is not assignable to type 'Nullable<string>'.
Type 'number' is not assignable to type 'Nullable<string>'.
All the suggested solutions of stackoverflow questions to this error like this one or this one don't fit to my problem AFAIK. I found a bad workaround, which I don't like using a Change Event instead of v-model in my template block and having the same error in my script but ignore it via //@ts-ignore
.
First, all I really ask for is how to comment out a typescript error in a VueJs template block, already asked here.
Second, how do I solve this problem without having a typescript error?
Looking at the piece of code below, I have this error at v-model
and don't know how to fix it:
<script setup lang="ts">
import { useMembershipStore } from "@/stores/membership";
const membershipStore = useMembershipStore();
membershipStore.getMembership();
const { membership } = storeToRefs(membershipStore);
function save() {
if (membership.value) {
membershipStore.updateMembership(membership.value);
}
}
</script>
<template>
<div v-if="membership === null" class="loading">
<h2>Loading</h2>
</div>
<div v-else class="members-table">
<div v-for="(value, key) in Object.keys(membership)" >
<br />
<InputText type="text"
v-model="membership[value as keyof typeof membership]"
/>
</div>
<Button @click="save()" />
</div>
</template>
Here are my type definitions: membershipstore.ts
export type MembershipStoreState = {
membership: Member | null;
};
types.ts
export interface Member {
id?: number;
user_id?: string;
user_attr: string | null;
create_attr?: string | null;
admin_attr?: string | null;
}
I also figured out where the type Nullable<string>
comes from. It is from PrimeVues type definition of its component InputText, which can be found here:
export interface InputTextProps extends InputHTMLAttributes {
/**
* Value of the component.
*/
modelValue?: Nullable<string>;
}
Full code example can be found here
Full code example with bad workaround using a change event, here
I suppose you are defining membership: Member|null
to check for loader <div v-if="membership === null" class="loading">
You can try this instead
export type MembershipStoreState = {
membership: Member;
};
In HTML
<template>
<div v-if="Object.keys(membership).length === 0" class="loading">
<h2>Loading</h2>
</div>
<div v-else class="members-table">
<div v-for="(value, key) in membership" > // thanks to @Dimava's comment
<br />
<InputNumber v-if = "key === 'id' || key === 'user_id'"
v-model="membership[key]"
/>
<InputText type="text" v-else
v-model="membership[key]"
/>
</div>
<Button @click="save()" />
</div>
</template>
Object.keys(membership).length === 0
Will check if you have popullated any of the keys of your interface otherwise it will return true and your loading
will be visible