TypeScript에서 type predicate를 안전하게 사용하는 방법
10448 단어 TypeScript
TL;DR
import { isT, isNotT, defineIsT } from "safe-type-predicate";
// isA: (x: "a" | "b") => x is "a"
const isA = defineIsT((x: "a" | "b") =>
x === "a" ? isT(x) : isNotT()
);
GitHub
safe-type-predicate
typepredicate 및 그 문제점
TypeScript에는 type predicate 기능이 있습니다.
이것은 적당한 유형의 값
x
을 받아들여 boolean
으로 되돌아오는 함수의 되돌아오는 값을 x is T
로 작성함으로써 되돌아오는 경우true
가 되돌아오는 것이 아니라x
형, T
는 그렇지 않다는 것을 나타낸다.이로써 사용자 정의 함수로 형 보호를 할 수 있다.
예를 들어, 반환
false
형, 즉 임의의 형을 받아들이고 그 값이 unknown
형인 함수는 다음과 같다.function isString(x: unknown): x is string {
return typeof x === "string";
}
이것은 편리한 기능이지만 매우 큰 문제가 존재한다.그것은 금형 검사가 거의 작용하지 않는 것이다.예를 들어 아래의 코드는 실제로는
string
형의 함수인지 아닌지를 판정하지만 금형에서는 number
형의 함수가 된다.function isString(x: unknown): x is string {
return typeof x === "number";
}
이 정도의 단순한 예라도 유형 검사를 하지 않기 때문에 약간의 오류가 오류의 원인이 되기 쉽다.따라서 이 글은 typepredicate를 안전하게 사용하는 방법과 이를 라이브러리화하는 방법
string
을 소개했다.typepredicate 안전한 사용 방법
typepredicate의 안전 처리는
safe-type-predicate
를 안전하게 정의하는 함수입니다.물론 TypeScript이기 때문에 완전히 안전하기는 어렵습니다.따라서 일정한 작법만 따르면 안전을 목표로 한다.
그리고 이를 실현하기 위해 형 방어와 형 추론을 잘 활용하는 것을 고려했다.
그리고 다음과 같은 표현을 쓸 수 있었으면 좋겠어요.
const isHoge = defineIsT((x: /* 引数に取る型 */) =>
/* 条件式 */ ? isT(x) : isNotT()
);
이렇게 쓰면 조건식(x: T) => x is R
의 시각isT(x)
이 형보호에 의해 축소되기 때문에 형추리를 할 수 있다.또한 값(즉, JS에 대한 컴파일 결과)을 고려하여
x
항등함수, defineIsT
및 isT
각각isNotT
, true
상수함수로 간단하게 할 수 있다.남은 것은 단지 잘 정형화되었을 뿐이다.
그것으로 만든 것은 아래와 같다.
declare const isTSymbol: unique symbol;
declare const isNotTSymbol: unique symbol;
export type isT<T> = true & { _T: T; _Tag: typeof isTSymbol };
export type IsNotT = false & { _Tag: typeof isNotTSymbol };
export function isT<T>(_x: T): isT<T> {
return true as isT<T>;
}
export function isNotT(): IsNotT {
return false as IsNotT;
}
export function defineIsT<T, R extends T>(
f: (x: T) => isT<R> | IsNotT
): (x: T) => x is R {
return f as any;
}
false
new type과 유령형의 기교를 사용하고, IsT<T>
new type의 기교를 사용한다.new type은 원래 타입으로 바꿀 수 있지만 원래 타입으로 보면 배우가 없으면 바꿀 수 없는 타입입니다.이것 없이도 동작할 수 있지만
IsNotT
, isT
의 반환값 이외의 값이 들어오는 것을 방지할 수 있기 때문에 더욱 안전하다.여기는isNotT
과& { _Tag: typeof isTSymbol }
의 부분입니다.유령형은 유형에 따라 서로 다른 유형의 정보를 남기는 기교이다.여기에는
& { _Tag: typeof isNotTSymbol }
의 부분에 & { _T: T }
의 유형 정보를 남긴다.이것을 사용하면 다음과 같은 내용을 쓸 수 있다.
// isString: (x: unknown) => x is string
const isString = defineIsT((x: unknown) =>
typeof x === "string" ? isT(x) : isNotT()
);
그리고 여기에 쓰인 사연은 T
이라는 이름으로 라이브러리화되어 공개됐다.사용자 정의 문자열 규칙
사용
safe-type-predicate
을 통해 아무것도 하지 않는 것보다 typepredicate를 안전하게 사용할 수 있습니다.그러나 다음과 같은 기법을 사용하면 당연형 시스템과 동작이 모순된다.
// isString: (x: unknown) => x is string
const isString = defineIsT((x: unknown) =>
isT("x")
);
'일정한 작법만 따르면 안전하다'는 목표로 만들어진 라이브러리이기 때문이다.따라서'일정한 작법'을 강제하면 되지 않겠느냐는 점을 고려해 tslint 규칙을 제정해
safe-type-predicate
의 이름으로 공개했다.tslint-safe-type-predicate
, npm i -D tslint-safe-type-predicate
의tslint.json
에 추가extends
만 하면 사용할 수 있다.예를 들어 위의 예에서 다음과 같은 경고를 보냅니다.
Reference
이 문제에 관하여(TypeScript에서 type predicate를 안전하게 사용하는 방법), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/kgtkr/items/7e4f18224c3362ceceeb텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)