Home  >  Q&A  >  body text

The rewritten title is: VueJS Typescript v-model type 'number' cannot be assigned to type 'Nullable<string>'

<p>So I'm new to Typescript and VueJS and all their new features. </p><p> Everything works as expected, but I can't get rid of the typescript errors and use v-model at the same time. </p><p> I'm developing a network view for members to inspect and change their properties. I am getting member data from API and storing it in PiniaStore. This means that I have several input fields that require members to be numbers and strings. AFAIK v-model is the best choice for input fields. </p> <pre class="brush:bash;toolbar:false;"> Type 'string | number | null | undefined' is not assignable to type 'Nullable<string>'. Type 'number' is not assignable to type 'Nullable<string>'. </pre> <p>All the suggested solutions to stackoverflow questions about this error (like this one or this one) don't fit my problem. I found a bad workaround, I don't like using change event in template block instead of v-model and I got the same error in my script but by <code>//@ts-ignore< /code> Ignore it. </p> <p>First of all, what I'm really asking for is how to comment out typescript errors in VueJs template blocks, which has already been asked here. </p><p> Secondly, how can I solve this problem without getting typescript errors? </p> <p>Looking at the code below, I'm getting this error at <code>v-model</code> and don't know how to fix it: </p> <pre class="brush:bash;toolbar:false;"><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> </pre> <p>This is my type definition: <strong>membershipstore.ts</strong></p> <pre class="brush:bash;toolbar:false;">export type MembershipStoreState = { membership: Member | null; }; </pre> <p><strong>type.ts</strong></p> <pre class="brush:bash;toolbar:false;">export interface Member { id?: number; user_id?: string; user_attr: string | null; create_attr?: string | null; admin_attr?: string | null; } </pre> <p>I also figured out where the <code>Nullable<string></code> type comes from. It comes from the PrimeVues type definition of its component InputText, which can be found here: </p> <pre class="brush:bash;toolbar:false;">export interface InputTextProps extends InputHTMLAttributes { /*** Value of the component.*/ modelValue?: Nullable<string>; } </pre> <p>Full code examples can be found here</p><p> Full code example using change events with workaround for error</p>
P粉863295057P粉863295057392 days ago527

reply all(1)I'll reply

  • P粉779565855

    P粉7795658552023-08-26 09:26:56

    I think you are defining membership: Member|null to check the loader

    You can try this

    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 populated any keys of the interface, otherwise it will return true and your Loading will be visible

    reply
    0
  • Cancelreply