Typescript - powtórzenia kodu przy sprawdzaniu typu za pomocą "is"

0

Załóżmy, że mam wiele takich obiektów:

const Handler1 = {
  name: 'h1',
  is(params: any): params is { id: number } {
    return Number.isInteger(params.id);
  },
  exec: (params: { id: number }) => {
    return;
  }
}

const Handler99 = {
  name: 'h2',
  is(params: any): params is { name: string } {
    return typeof params.string === undefined;
  },
  exec: (params: { name: string }) => {
    return;
  }
}

const data = JSON.parse("{id: 123}")
const handlerName = Math.random() > 0.5 ? 'h1' : 'h99';

każdy obiekt ma funkcję is, która sprawdza i typuje argument dla funkcji exec. W ten sposób wszystko działa:

if (Handler1.name === handlerName && Handler1.is(data)) {
  Handler1.exec(data)
}

/*... */

if (Handler99.name === handlerName && Handler99.is(data)) {
  Handler99.exec(data)
}

ale chciałbym to uprościć do czegoś takiego:

const handlers = [Handler1, Handler99]
const handler = handlers.find(h => h.name === handlerName)

if (handler.is(data)) {
  handler.exec(data)
}

ale przy wywołaniu handler.exec(data) dostaję błąd: Argument of type '{ id: number; } | { name: string; }' is not assignable to parameter of type '{ id: number; } & { name: string; }'.
Type '{ id: number; }' is not assignable to type '{ id: number; } & { name: string; }'.
Property 'name' is missing in type '{ id: number; }' but required in type '{ name: string; }'

Mogę to oczywiście obejść przez ``handler.exec(data as any)` ale szukam lepszego sposobu.

1

return typeof params.string === undefined;

To nigdy nie będzie prawdziwe, bo typeof zwraca stringa (więc co najwyżej "undefined"). Ale to pewnie poboczny błąd.

0

A takie zdefiniowanie typu parametu

  exec: (params: { id: number } | { name: string }) => {
      return;
    }
1

Nie ma innego sposobu niż przez handler.exec(data as any). Każdy z nich, to hackowanie typów, a ten jest najprostszy ;) Możesz zrobić z tego klasy i spiąć to interfejsem, ale efekt będzie ten sam, bo w interfejsie będziesz musiał napisać param: any, a w implementacjach już konkretne typy. Po prostu w inny sposób oszukasz TypeScripta.

1 użytkowników online, w tym zalogowanych: 0, gości: 1