Зачем мне приводить `как NonNullable <T>` после проверки на null и undefined? - PullRequest
4 голосов
/ 15 апреля 2020
// This is an implementation of https://msdn.microsoft.com/visualfsharpdocs/conceptual/seq.choose%5b%27t%2c%27u%5d-function-%5bfsharp%5d
const choose = <T, U>(
  collection: T[],
  selector: (elem: T) => U
): NonNullable<U>[] => {
  const result: NonNullable<U>[] = [];
  for (const element of collection) {
    const value = selector(element);
    if (value !== undefined && value !== null) {
      // result.push(value); TypeScript complains that U is not convertible to NonNullable<U>
      result.push(value as NonNullable<U>); // this works
    }
  }
  return result;
};

Зачем мне нужен там актерский состав, и есть ли способ напечатать это, чтобы мне это не нужно? TypeScript обычно может сказать, что что-то не может быть нулевым или неопределенным внутри оператора if, который проверяет эти случаи.

1 Ответ

1 голос
/ 15 апреля 2020

Есть несколько способов решения. Вы можете просто удалить встроенный typedef для result

const choose = <T, U>(
  collection: T[],
  selector: (elem: T) => U
): NonNullable<U>[] => {
  const result = [];
  for (const element of collection) {
    const value = selector(element);
    if (value !== undefined && value !== null) {
      result.push(value); // this works
    }
  }
  return result;
};

. Учитывая, что вы переносите это из F #, лучшим решением для вас может быть включение строгих нулевых проверок в ваш tsconfig. json, чтобы хотя вам не нужно явно указывать NonNullable во-первых.


//with "strictNullChecks": true in your tsconfig.json
const choose = <T, U>(
  collection: T[],
  selector: (elem: T) => U
): U[] => {
  const result = [];
  for (const element of collection) {
    const value = selector(element);
    if (value !== undefined && value !== null) {
       result.push(value);
       //result.push(undefined);  //can't do this and also return result
    }
  }
  return result;
};

Если вы нажали undefined на result и попытались вернуть result, компилятор пожаловался бы, что Тип результата функции должен быть U | undefined

Вы можете также принять концепцию неизменности с чем-то вроде этого.

const choose = <T, U>(collection: T[], selector: (elem: T) => U): U[] =>
  collection.reduce((p, c) => {
    const value = selector(c);
    return value ? [...p, value] : p;
  }, []);

В любом случае, я бы предложил включить strictNullChecks, если вы заинтересованы в работе с эффектом undefined (возможно, Option, как бы вы это ни называли)

По комментариям

Ожидается, что функция селектора вернет значение null или неопределенное значение.

В этом случае я бы предложил вызвать это в подпись функции

const choose = <T, U>(collection: T[], selector: (elem: T) => U | undefined): U[] => {
  const result = [];
  for (const element of collection) {
    const value = selector(element);
    if (value) result.push(value);
  }
  return result;
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...