admin管理员组

文章数量:1315101

I'm struggling to get over an error on TS.

I define value (below in the code) according 2 interfaces that I created (WalletInformationsEdit and UserInformationsEdit)

The problem that I encounter is at the line right after the DB query, value[field] is underlined saying :

Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'WalletInformationsEdit | UserInformationsEdit'.
  No index signature with a parameter of type 'string' was found on type 'WalletInformationsEdit | UserInformationsEdit'.

I have find 2 solutions to avoid this error message, but I am not ok because they make my code less protected:

1/ In TS config, if I take off "strict": true and "noImplicitAny": true -> working

2/ if I define value with "any" type, -> working

But both are not worth it, I suppose.

Do you have any remandation to handle this case ?

Thanks in advance,

Paul

    public async update(value: WalletInformationsEdit | UserInformationsEdit): Promise<any> {

        try {

            // saving id before elem treatment
            const keepId = value.id
            delete value.id

            let filterFields = []
            for (let elem of Object.keys(value)) {
                filterFields.push(elem)
            }

            let i = 0;
            let updateList = [];
            for (const field of filterFields) {
              updateList.push(`"${field}" = $${++i}`);
            }

            const preparedQuery = {
              text: `UPDATE "${this.constructor.name.toLowerCase()}" SET
                    ${updateList.join()}
                  WHERE id = $${++i}
                  RETURNING *
              `,
              values: [...filterFields.map((field) => value[field]), keepId],
            };            

            const result = await db.query(preparedQuery);            

            return result.rows[0]

        } catch (error) {
            throw new Error(error.message)

        }


    }

WalletInformationsEdit and UserInformationsEdit interfaces

export interface UserInformationsEdit {
    id?: number,
    email?: string,
    password?: string,
    country?: string
}

export interface WalletInformationsEdit {
    id?: number,
    name?: string,
    is_default?: boolean,
}

I'm struggling to get over an error on TS.

I define value (below in the code) according 2 interfaces that I created (WalletInformationsEdit and UserInformationsEdit)

The problem that I encounter is at the line right after the DB query, value[field] is underlined saying :

Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'WalletInformationsEdit | UserInformationsEdit'.
  No index signature with a parameter of type 'string' was found on type 'WalletInformationsEdit | UserInformationsEdit'.

I have find 2 solutions to avoid this error message, but I am not ok because they make my code less protected:

1/ In TS config, if I take off "strict": true and "noImplicitAny": true -> working

2/ if I define value with "any" type, -> working

But both are not worth it, I suppose.

Do you have any remandation to handle this case ?

Thanks in advance,

Paul

    public async update(value: WalletInformationsEdit | UserInformationsEdit): Promise<any> {

        try {

            // saving id before elem treatment
            const keepId = value.id
            delete value.id

            let filterFields = []
            for (let elem of Object.keys(value)) {
                filterFields.push(elem)
            }

            let i = 0;
            let updateList = [];
            for (const field of filterFields) {
              updateList.push(`"${field}" = $${++i}`);
            }

            const preparedQuery = {
              text: `UPDATE "${this.constructor.name.toLowerCase()}" SET
                    ${updateList.join()}
                  WHERE id = $${++i}
                  RETURNING *
              `,
              values: [...filterFields.map((field) => value[field]), keepId],
            };            

            const result = await db.query(preparedQuery);            

            return result.rows[0]

        } catch (error) {
            throw new Error(error.message)

        }


    }

WalletInformationsEdit and UserInformationsEdit interfaces

export interface UserInformationsEdit {
    id?: number,
    email?: string,
    password?: string,
    country?: string
}

export interface WalletInformationsEdit {
    id?: number,
    name?: string,
    is_default?: boolean,
}
Share Improve this question edited Nov 11, 2020 at 16:48 x2cheese asked Nov 11, 2020 at 16:32 x2cheesex2cheese 3332 gold badges6 silver badges17 bronze badges 4
  • 1 Can you include the WalletInformationsEdit and UserInformationsEdit interfaces? See basarat.gitbook.io/typescript/type-system/index-signatures. – Brian Lee Commented Nov 11, 2020 at 16:35
  • hey, I have added both interfaces above – x2cheese Commented Nov 11, 2020 at 16:48
  • You could try to implement generics to the function. – ricardo-dlc Commented Nov 11, 2020 at 17:52
  • thanks you for your response, I have tried to understand how work index signature, and tried to get declarations from the interfaces like [id: string]: number ... but it does not work. Do you have an exemple to use it in my case ? – x2cheese Commented Nov 11, 2020 at 18:56
Add a ment  | 

2 Answers 2

Reset to default 6

I finally find the answer, to declare the index signature in my case, i had to declare it this way

export interface WalletInformationsEdit {
    [key: string]: number | string | boolean | undefined;
    id?: number,
    name?: string,
    is_default?: boolean

} 

[key: string] -> index is read as a string

: number | string | boolean | undefined -> each type that posed my interface + undefined because properties are optional

thanks @DigitalDrifter for the link :-)

In this case, you're sure that the field is a key of value. So you can type it like this.

filterFields.map((field: keyof typeof value) => value[field])

本文标签: