유형 스크립트 어설션과 같은 유형 가드
다음을 제외하고 유형을 제한할 수 있습니까?if
함수 호출에 의해never
예를 들어 반환undefined
맘에 들다assert
유형 스크립트에서?
코드 예제:
interface Foo { bar(): void }
function getFoo(): Foo | undefined { }
function test() {
const foo = someService.getFoo();
assert(foo);
if (!foo) { // now mandatory because without this foo may be still undefined even if assert protects us from this
return;
}
foo.bar(); // , here foo may be undefined
}
나는 글을 쓸 수 있기를 원합니다.assert
내가 따라가지 않을 수 있는 방법으로.if (!foo)
절과 을 가지다.foo
평문으로 제한된 활자Foo
.
Typescript에서 이것이 가능합니까?
오버로드를 추가해 보았습니다.never
다음을 던지는 유형:
function assertGuard(v: undefined | null | '' | 0 | false): never;
function assertGuard(v: any): void; // i'm not sure which one is captured by TS typesystem here
function assertGuard<T>(v: T | undefined) {
if (v === undefined || v === null || v === '' || v === 0 || v === false) {
throw new AssertionError({message: 'foo'})
}
}
이것은 컴파일하지만 호출합니다.assertGuard(foo)
에 대해 그것을 인식하지 못합니다.undefined
돌아올 것입니다.never
그래서 제한하지 않습니다.foo
로.Foo
.
가능한 해결책을 찾았지만 고전적이라고 생각합니다.assert
보다 깔끔한 접근 방식:
function assertResultDefined<T>(v: T|undefined): T | never {
if (v === undefined) {
throw new Error('foo');
}
return v;
}
function die(): never { throw new Error('value expected)}
const foo = assertResultDefined(getFoo()) // foo is Foo, undefined is erased
const foo = getFoo() || die();
// undefined is erased from foo
/ CONS: doesn't play well with types that interpolate to `false` like 0, ''
유형 스크립트 3.7은 제어 흐름 분석에 주장을 추가합니다.
안
asserts
반환 형식 술어는 어설션이 유지될 때만 함수가 반환되고 그렇지 않을 때는 예외를 반환함을 나타냅니다.
소비자 측의 해킹은 더 이상 필요하지 않습니다.
interface Foo { bar(): void }
declare function getFoo(): Foo | undefined;
function assert(value: unknown): asserts value {
if (value === undefined) {
throw new Error('value must be defined');
}
}
function test() {
const foo = getFoo();
// foo is Foo | undefined here
assert(foo);
// foo narrowed to Foo
foo.bar();
}
또한 제공된 매개 변수가 필수 유형이라고 주장할 수 있습니다.
declare function assertIsArrayOfStrings(obj: unknown): asserts obj is string[];
function foo(x: unknown) {
assertIsArrayOfStrings(x);
return x[0].length; // x has type string[] here
}
이 https://github.com/Microsoft/TypeScript/issues/8655 에 대한 유형 스크립트 백로그에 문제가 있습니다.그래서 지금은 이것을 할 수 없습니다.
당신이 할 수 있는 것은 어설션 연산자 "!"를 사용하는 것입니다.! 뒤에 값을 추가하면 값이 정의되지 않았거나 null이 아닙니다.null 또는 정의되지 않은 참조로 이어질 수 없다고 확신하는 경우 사용합니다.
function test() {
const foo: (FooType|null) = getFoo();
foo!.bar(); // "!" - asserts that foo is not null nor undefined
}
출처: https://www.typescriptlang.org/docs/handbook/advanced-types.html#type-guards-and-type-assertions
부터foo
이라Foo | undefined
그것의 유형은 로 변경되어야 합니다.Foo
어떻게든.
위의 코드에서 이 작업은 다음을 통해 수행할 수 있습니다.
let foo = getFoo(); // Foo | undefined
foo = assertResultDefined(foo); // Foo
foo.bar();
또 다른 옵션은 null이 아닌 어설션을 사용하는 것입니다(다른 답변에서 알 수 있듯이).
let foo = getFoo();
foo = assertResultDefined(foo);
foo = foo!;
foo.bar();
이것은 당신에게 효과가 있을 것입니다.
const foo = (a: number | null) => {
a = shouldBe(_.isNumber, a)
a // TADA! a: number
}
const shouldBe = <T>(fn: (t1) => t1 is T, t) => (fn(t) ? t : throwError(fn, t))
const throwError = (fn:Function, t) => {
throw new Error(`not valid, ${fn.name} failed on ${t}`)
}
어디에_.isNumber
타입 가드가 있습니다.x is number
이것은 타입 가드와 함께 어떤 기능에도 사용할 수 있습니다.
핵심은 변수를 재할당해야 하기 때문에 효과적으로assert
실패한 유형 어설션에 오류를 발생시키는 ID 함수입니다.
형식 안전성이 있는 원라이너:
function assert<T>(value: T | undefined): T {
if (value === undefined) {
throw new Error('value is undefined');
}
return value;
}
언급URL : https://stackoverflow.com/questions/49362725/typescript-assert-like-type-guard
'programing' 카테고리의 다른 글
파일을 다운로드한 후 Ajax를 통해 다른 페이지로 리디렉션 (0) | 2023.07.24 |
---|---|
정의되지 않은 검사 후에도 유형 스크립트 "error TS2532: 개체가 '정의되지 않음'일 수 있음" (0) | 2023.07.19 |
Numpy를 사용하여 파생물을 어떻게 계산합니까? (0) | 2023.07.19 |
파이썬에서 문자열을 타이틀 케이스로 변환하는 방법은 무엇입니까? (0) | 2023.07.19 |
예외를 발생시키는 람다 식 정의 (0) | 2023.07.19 |