TypeScript, –strictNullChecks 모드.
nullable 문자열 배열 (string | null) []이 있다고 가정합니다. 결과가 string [] 유형을 갖는 방식으로 모든 널을 제거 하는 단일 표현식 방법 은 무엇입니까 ?
const array: (string | null)[] = ["foo", "bar", null, "zoo", null];
const filterdArray: string[] = ???;
Array.filter는 여기서 작동하지 않습니다.
// Type '(string | null)[]' is not assignable to type 'string[]'
array.filter(x => x != null);
배열 이해는 작동 할 수 있지만 TypeScript에서 지원되지 않습니다.
실제로 질문은 공용체에서 특정 유형을 가진 항목을 제거하여 모든 공용체 유형의 배열을 필터링하는 문제로 일반화 될 수 있습니다. 그러나 가장 일반적인 사용 사례이므로 null 및 undefined 인 공용체에 중점을 둡니다.
답변
엄격한 유형 검사에서 옵트 아웃하지 않도록 에서 유형 술어 함수를 사용할 수 있습니다 .filter
.
function notEmpty<TValue>(value: TValue | null | undefined): value is TValue {
return value !== null && value !== undefined;
}
const array: (string | null)[] = ['foo', 'bar', null, 'zoo', null];
const filteredArray: string[] = array.filter(notEmpty);
또는 array.reduce<string[]>(...)
.
답변
@ bijou-trouvaille의 답변과 유사하게 <arg> is <Type>
필터 함수의 출력으로 를 선언하면 됩니다.
array.filter((x): x is MyType => x !== null);
답변
더 많은 사람들이 종종 잊어으로 좋은 측정을위한 하나의 flatMap
처리 수 filter
및 map
(이것은 또한 어떤 캐스팅을 필요로하지 않는 한 번에 string[]
) :
// (string | null)[]
const arr = ["a", null, "b", "c"];
// string[]
const stringsOnly = arr.flatMap(f => typeof f === "string" ? [f] : []);
답변
filter
결과를 원하는 유형으로 캐스팅 할 수 있습니다 .
const array: (string | null)[] = ["foo", "bar", null, "zoo", null];
const filterdArray = array.filter(x => x != null) as string[];
이것은 언급 한보다 일반적인 사용 사례에서 작동합니다. 예를 들면 다음과 같습니다.
const array2: (string | number)[] = ["str1", 1, "str2", 2];
const onlyStrings = array2.filter(x => typeof x === "string") as string[];
const onlyNumbers = array2.filter(x => typeof x === "number") as number[];
( 놀이터의 코드 )
답변
유형 검사가 필터링 된 유형을 반환 유형과 다르지 않게 만드는 것을 제외하고는 모든 것이 좋다고 생각합니다.
const array: (string | null)[] = ["foo", "bar", null, "zoo", null];
const filterdArray: string[] = array.filter(f => f !== undefined && f !== null) as any;
console.log(filterdArray);
답변
또 다시 나는 함수가 호출 번들을 통해 동일한 유형의 가드 도우미 함수를 작성하는 데 모든 사람을 피하기 위해 isPresent
, isDefined
그리고 isFilled
헬퍼 라이브러리로 : https://www.npmjs.com/package/ts-is-present
현재 유형 정의는 다음과 같습니다.
export declare function isPresent<T>(t: T | undefined | null): t is T;
export declare function isDefined<T>(t: T | undefined): t is T;
export declare function isFilled<T>(t: T | null): t is T;
다음과 같이 사용할 수 있습니다.
import { isDefined } from 'ts-is-present';
type TestData = {
data: string;
};
const results: Array<TestData | undefined> = [
{ data: 'hello' },
undefined,
{ data: 'world' }
];
const definedResults: Array<TestData> = results.filter(isDefined);
console.log(definedResults);
Typescript가이 기능을 번들로 제공 할 때 패키지를 제거하겠습니다. 그러나 지금은 즐기십시오.
답변
이미 Lodash를 사용하고 있다면 compact
. 또는 Ramda를 선호하는 경우 ramda-adjunct도 compact
작동합니다.
둘 다 유형이 있으므로 tsc가 만족하고 결과적으로 올바른 유형을 얻습니다.
Lodash d.ts 파일에서 :
/**
* Creates an array with all falsey values removed. The values false, null, 0, "", undefined, and NaN are
* falsey.
*
* @param array The array to compact.
* @return Returns the new array of filtered values.
*/
compact<T>(array: List<T | null | undefined | false | "" | 0> | null | undefined): T[];