简体   繁体   English

如何在类型级别断言一个类型不是任何类型?

[英]How to type-level assert a type is not any?

I'm using a type-level Assert function to make assertions about the type-inferencing in my code.我正在使用类型级Assert function 对我的代码中的类型推断进行断言。 However, I'm not able to make any assertions about a type not being any .但是,我无法对不是any的类型做出任何断言。

type Assert<A extends ShouldBe, ShouldBe> = A

// @ts-expect-error
type SubsetObj = Assert<{ id: string }, { id: string; name: string }>
type SameObj = Assert<
    { id: string; name: string },
    { id: string; name: string }
>
type ExceedsObj = Assert<{ id: string; name: string }, { id: string }>

type SubsetUnion = Assert<number, number | string>
type SameUnion = Assert<number | string, number | string>

// @ts-expect-error
type ExceedUnion = Assert<number | string, number>

// @ts-expect-error 👈 this is what I want to work.
type AnyShouldWork = Assert<any, number>

I've tried a few things with no avail.我尝试了一些无济于事的事情。 I noticed that unknown works as expected我注意到unknown按预期工作

// @ts-expect-error
type AssertUnknown = Assert<unknown, number>

And so I tried this code:所以我尝试了这段代码:

type IsAny<T> = unknown extends T ? (T extends {} ? T : never) : never
type NotAny<T> = T extends IsAny<T> ? unknown : T

type Assert2<A extends ShouldBe, ShouldBe> = Assert<NotAny<A>, ShouldBe>

// @ts-expect-error
type AssertAny = Assert2<any, number>

But this doesn't work because Assert<NotAny<A>, ShouldBe> fails right off the bat because NotAny can return unknown...但这不起作用,因为Assert<NotAny<A>, ShouldBe>失败,因为NotAny可以返回未知......

So I'm kind of stuck here... Any ideas?所以我有点被困在这里......有什么想法吗?

I think it is better and much easier to use extra Equals helper:我认为使用额外的Equals助手更好也更容易:


// credits goes to https://github.com/microsoft/TypeScript/issues/27024#issuecomment-421529650
export type Equals<X, Y> =
  (<T>() => T extends X ? 1 : 2) extends
  (<T>() => T extends Y ? 1 : 2) ? true : false;


type AssertTrue<A extends true> = A

// @ts-expect-error
type Test1 = AssertTrue<Equals<any, number>>
// @ts-expect-error
type Test2 = AssertTrue<Equals<unknown, number>>
// @ts-expect-error
type Test3 = AssertTrue<Equals<number | string, number>>
// @ts-expect-error
type Test4 = AssertTrue<Equals<{ id: string }, { id: string; name: string }>>

You can also use the https://github.com/TypeStrong/ts-expect with TypeEqual the package provides.您还可以使用https://github.com/TypeStrong/ts-expectTypeEqual提供的 TypeEqual。

import { expectType, TypeEqual } from "ts-expect";
import { add } from "./adder";

expectType<number>(add(1, 2));
expectType<TypeEqual<number, ReturnType<typeof add>>>(true);
expectType<TypeEqual<[number, number], Parameters<typeof add>>>(true);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM