react native - Const-variabel som type - Typescript


Under læring av Typescript møtte jeg et problem når jeg brukte en konstant variabel med verdien av handlingen som jeg bruker i reduceren (laget for å forhindre skrivefeil - jeg har lest et sted at det er god praksis).

const INPUT_CHANGE: string = "INPUT_CHANGE";
const INPUT_BLUR: string = "INPUT_BLUR";

Jeg har også laget en type for å definere reducer-handling:

type InputReducerAction =
  | { type: INPUT_CHANGE; value: string; isValid: boolean }
  | { type: INPUT_BLUR };

Og her er min reduser:

const inputReducer = (state: InputReducerState, action: InputReducerAction) => {
  switch (action.type) {
    case INPUT_CHANGE:
      return {
        ...state,
        value: action.value,
        isValid: action.isValid,
      };
    case INPUT_BLUR:
      return {
        ...state,
        touched: true,
      };
    default:
      return state;
  }
};

Når jeg har alt som ovenfor, blir INPUT_CHANGE og INPUT_BLUR i InputReducerAction markert som feil:

'INPUT_CHANGE' refererer til en verdi, men brukes som en type her. Mente du 'typeof INPUT_CHANGE'?ts(2749)

'INPUT_BLUR' refererer til en verdi, men brukes her som en type. Mente du 'typeof INPUT_BLUR'?ts(2749)

Problemet forsvinner når jeg bruker doble anførselstegn for disse konstantene, slik

type InputReducerAction =
  | { type: "INPUT_CHANGE"; value: string; isValid: boolean }
  | { type: "INPUT_BLUR" };

Men mine const-variabler er ubrukelige akkurat nå. Hva har jeg gjort feil eller oversett?

Mens jeg skrev dette spørsmålet, fikk jeg ideen om å bruke enum:

enum INPUT_ACTION {
  INPUT_CHANGE = "INPUT_CHANGE",
  INPUT_BLUR = "INPUT_BLUR"
}

type InputReducerAction =
  | { type: INPUT_ACTION.INPUT_CHANGE; value: string; isValid: boolean }
  | { type: INPUT_ACTION.INPUT_BLUR };

const inputReducer = (state: InputReducerState, action: InputReducerAction) => {
  switch (action.type) {
    case INPUT_ACTION.INPUT_CHANGE:
      return {
        ...state,
        value: action.value,
        isValid: action.isValid,
      };
    case INPUT_ACTION.INPUT_BLUR:
      return {
        ...state,
        touched: true,
      };
    default:
      return state;
  }
};

og bruke det i reducer og type. Feilene forsvinner, MEN er det en god idé eller kan jeg gjøre dette på en bedre måte

Svar #1

Du kan bruke const-påstander etter v3.4 for å gjøre det du beskriver.

const INPUT_CHANGE = "INPUT_CHANGE" as const;
const INPUT_BLUR = "INPUT_BLUR" as const;

type InputReducerAction =
  | { type: typeof INPUT_CHANGE; value: string; isValid: boolean }
  | { type: typeof INPUT_BLUR };

const changeAction: InputReducerAction = {
  type: INPUT_CHANGE, value: '', isValid: false
};

const blurAction: InputReducerAction = {
  type: INPUT_BLUR
};

Problemet er at JavaScript-variablene kun vil få verdiene sine tilordnet ved kjøring, og TypeScript må vite det under kompilering. Å bruke const-assertions er en måte å informere kompilatoren om at verdiene deres ikke skal endres. Og når du bruker typeof på variabelen, brukes den bokstavelige verdien i stedet for den generiske string-typen som normalt blir tilordnet variabelen.

Relaterte artikler