programing

TypeScript 컴파일러 Array.protype을 확인하는 방법.필터가 어레이에서 특정 유형을 제거합니까?

easyjava 2023. 3. 15. 20:02
반응형

TypeScript 컴파일러 Array.protype을 확인하는 방법.필터가 어레이에서 특정 유형을 제거합니까?

Array.protype을 사용하여 배열에서 늘(정의되지 않은) 요소를 필터링하려고 합니다.Filter 하지만 TypeScript 컴파일러가 "filter" 함수의 파생 배열을 인식하지 못하고 유형 검사를 통과하지 못했습니다.

(number | undefined) [ ]타입의 배열이 있고 번호[ ]어레이에 적합하도록 필터가 정의되어 있지 않은 경우, 다음과 같은 간단한 코드가 있다고 가정합니다.

const arry = [1, 2, 3, 4, "5", 6];
const numArry: number[] = arry
    .map((i) => {
        return typeof i === "number" ? i : void 0;
    })
    .filter((i) => i);

에러:

유형 '(number | undefined)'[]는 유형 'number[]'에 할당할 수 없습니다.유형 'number | undefined'는 유형 'number'에 할당할 수 없습니다.'undefined' 유형은 'number' 유형에 할당할 수 없습니다.

필터 기능 삭제가 정의되어 있지 않은 것을 알고, 아래와 같이 결과 어레이를 번호[]에 캐스트 할 수 있습니다.

const arry = [1, 2, 3, 4, "5", 6];
const numArry: number[] = (arry
    .map((i) => {
        return typeof i === "number" ? i : void 0;
    })
    .filter((i) => i) as Number[]);

캐스팅 말고 더 좋은 방법이 있을까요?

환경: strict Null Checks가 유효하게 되어 있는 TSC2.1.

TypeScript 사용자 정의 유형 가드 기능 사용:

const arry = [1, 2, 3, 4, "5", 6];
const numArry: number[] = arry
    .filter((i): i is number => {
        return typeof i === "number";
    });
// numArry = [1, 2, 3, 4, 6]

을 보다.i is number콜백 함수로 설정합니다.이 트릭을 사용하면 Array.filter 결과의 유형을 캐스팅할 수 있습니다.

솔루션

유형 가드를 만듭니다.

function isDefined<T>(argument: T | undefined): argument is T {
    return argument !== undefined
}

형식 술어로 사용합니다.

const foo: number[] = [1, 2, undefined, 4].filter(isDefined)

설명.

Array.prototype.filter과부하가 몇 개 있습니다.그 중 하나는 반환값이 술어 함수에 따라 달라진다는 것을 알고 있습니다.타입 가드를 사용합니다.

filter<S extends T>(callbackfn: (value: T, index: number, array: T[]) => value is S, thisArg?: any): S[];

(숏컷을 사용하여 암묵적인 강제성에 의존하지 않고) 적절한 타입 가드를 사용하면 TypeScript가 이 특정 과부하를 선택할 수 있습니다.

Typescript가 이해하는 가장 쉬운 방법으로 배열에서 값을 필터링하는 방법은flatMap대신map빈 어레이를 반환하여 삭제할 수 있습니다.

예:

const myArray = [1,2,3,4,"5",6,7, undefined,9, 0]
const filteredArray = arr.flatMap(val => typeof val === "number" ? val : [])
// filteredArray: [ 1, 2, 3, 4, 6, 7, 9, 0 ]

flatMap는 2단계로 동작합니다.먼저 어레이에 매핑되어 지정한 기능을 실행합니다.그런 다음 그 안에 있는 모든 어레이를 평탄화합니다.

  1. 어레이에 매핑하여 다음 정보를 얻습니다.[ 1, 2, 3, 4, [], 6, 7, [], 9, 0 ]

  2. 어레이 내의 모든 어레이를 평탄화합니다.[ 1, 2, 3, 4, 6, 7, 9, 0 ]

부일라! 이제 타이프 배열이 생겼고 타이프 스크립트는 행복합니다.

여기에 이미지 설명 입력

어레이와 사용자 정의 타입 가드 함수를 받아들여 다른 타입의 어레이를 반환하는 완전 타입의 세이프 필터 함수를 정의할 수 있습니다.

얼마나 유용한지 모르겠지만, 여기 있습니다.

function typeFilter<T, R extends T>(a: T[], f: (e: T) => e is R): R[] {
    const r: R[] = [];
    a.forEach(e => { if (f(e)) r.push(e) });
    return r;
}

다음과 같이 사용할 수 있습니다.

const arry = [1, 2, 3, 4, "5", 6];

function isNumber(e): e is number {
    return typeof e === 'number';
}

const numArry: number[] = typeFilter(arry, isNumber);

★★★★★★★★★★★★★★★★★★★.isNumber()는, 함수 「」를 할 수 있을 개별적으로 가 있습니다.e => typeof e === 'number'타입 가드이기도 합니다.

map(...)함수 시그니처는 다음과 같습니다.

map<U>(callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any): U[];

의 경우 유형 " " " " " " "U 됩니다.number | undefined

filter(...)츠키다

filter(callbackfn: (value: T, index: number, array: T[]) => any, thisArg?: any): T[];        

★★★★★★★★★★★★★★★★★.T 인터페이스 시그니처 인터페이스 시그니처)에서 송신됩니다.Array<T>입니다.valueargument 인수())T)의 )입니다number | undefined.

타입은 ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★.number | undefined.

이를 바탕으로 캐스팅 표현식을 사용해야 합니다. 않는 는, 「」를 할 수 .--strictNullChecks

솔루션

const arry = [1, 2, 3, 4, "5", 6];
const numArry = arry.reduce((acc, x) => typeof x === 'number' ? [...acc, x] : acc, [] as number[]);

나는 활자 가드의 사용에 반대한다. 왜냐하면 당신은 실제로 어떤 논리든 쓸 수 있고 그것은 여전히 작동하기 때문이다.

function isNumber(e: any): e is number {
    return e === undefined;
}

const numArry = arry.filter(isNumber);

언급URL : https://stackoverflow.com/questions/43010737/way-to-tell-typescript-compiler-array-prototype-filter-removes-certain-types-fro

반응형