Artem
Artem

Reputation: 23

Type 'string' is not assignable to type 'never' in obj[key]

Help me, please. I don't understand what's wrong. I have a function that edits a form. I tried to set the param value of function "editCloneStateForm" type typeof this.form but it doesn't work too. My code:

editCloneStateForm (value: string, key: IServiceDoneItemKeys) {
    if (this.index >= 0) {
      this.cloneStateForm[this.index].cdate = value
    } else {
      this.form[key] = value // Type 'string' is not assignable to type 'never'
    }
  }

form: IServiceDoneItem = {
    id: 0,
    cdate: '',
    counterparty_id: '',
    counterparty_name: '',
    contract_id: '',
    contract_number: '',
    service_id: '',
    statement_id: null,
    service_count: 0,
    cost: 0,
    income: 0,
    agents_commission: 0,
    state_duty: 0,
    ukap: ''
  }
export interface IServiceDoneItem {
  id?: number,
  cdate: string,
  counterparty_id: number | string,
  counterparty_name: string,
  contract_id: number | string,
  contract_number: string,
  service_id: number | string,
  statement_id: number | null,
  service_count: number,
  cost: number,
  income: number,
  agents_commission: number,
  state_duty: number,
  ukap: string
}

export type IServiceDoneItemKeys = keyof IServiceDoneItem

Upvotes: 2

Views: 117

Answers (1)

Stu Behan
Stu Behan

Reputation: 51

Updated answer

The original answer would allow you to add any key to your object which might be something you want to avoid, you might only want those specific key/value pairs.

This would keep your interface strict to the specified keys:

editCloneStateForm(value: string, key: IServiceDoneItemKeys) {
  if (this.index >= 0) {
    this.cloneStateForm[this.index].cdate = value;
  } else {
    (this.form as Record<IServiceDoneItemKeys, IServiceDoneItem[keyof IServiceDoneItem]>)[key] = value;
  }
}

But you should probably check the type of the key as your value argument is typed as string so we would only want to assign keys which allow value types of string

Original answer

Typescript does not know which type the key you're accessing on your interface ISserviceDoneItem is in advance.

You could create a generic to extend:

export interface Dictionary<T> {
  [key: string]: T;
}

export interface IServiceDoneItem extends Dictionary<string | number | undefined | null> {
  id?: number;
  cdate: string;
  counterparty_id: number | string;
  counterparty_name: string;
  contract_id: number | string;
  contract_number: string;
  service_id: number | string;
  statement_id: number | null;
  service_count: number;
  cost: number;
  income: number;
  agents_commission: number;
  state_duty: number;
  ukap: string;
}

This will allow the types of any of your keys on your interface.

Upvotes: 1

Related Questions