Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Useless NoInfer #27

Open
sirian opened this issue Aug 6, 2018 · 4 comments
Open

Useless NoInfer #27

sirian opened this issue Aug 6, 2018 · 4 comments

Comments

@sirian
Copy link

sirian commented Aug 6, 2018

enum A {X = 1}

declare function assertEqual<T>(actual: T, expected: NoInfer<T>): boolean;
declare const a: A;
const x = 100;
assertEqual(a, x);
assertEqual(x, a);
declare const y: 100 | 101;
assertEqual(a, y);
assertEqual(y, a);
assertEqual(y, x);
assertEqual(x, y);

image

Another examples
image

image

@sirian
Copy link
Author

sirian commented Aug 6, 2018

There are 2 possible solutions to assert exact types

enum A {X = 1}

declare const y: 100 | 101;
const x = 100;

export type AssertExact1<T extends R, U extends R, R = T & U> = never;
type test1 = [
    AssertExact1<A, 100>,
    AssertExact1<100, A>,
    AssertExact1<A, 100 | 101>,
    AssertExact1<100 | 101, A>,
    AssertExact1<100 | 101, 100>,
    AssertExact1<100, 100 | 101>
    ];

export type AssertExact2<T extends [T[1], T[0]]> = never;
type test2 = [
    AssertExact2<[A, 100]>,
    AssertExact2<[100, A]>,
    AssertExact2<[A, 100 | 101]>,
    AssertExact2<[100 | 101, A]>,
    AssertExact2<[100 | 101, 100]>,
    AssertExact2<[100, 100 | 101]>
    ];

image

@pelotom
Copy link
Owner

pelotom commented Aug 6, 2018

Cool, care to make a PR?

@KiaraGrouwstra
Copy link

The assertEqual(a, y); yielding ok yet assertEqual(y, a); not ok, is that desired behavior?
I know that "allow iff there is potential overlap between the types" is really hard to do.
Failing that, I'm inclined to just not type params for functions like this, as anything else ends up wrong in some case.

@sirian
Copy link
Author

sirian commented Aug 6, 2018

@pelotom Sorry - have no time:(

@tycho01 that's why I use symmetric AssertExact from example above for testing typings

for example

export declare type ArgCount<F> =
    F extends (...args: infer A) => any ? A["length"] :
    F extends { new(...args: infer A): any } ? A["length"] :
    F extends Function ? number : never;

export type AssertExact<T extends R, U extends R, R = T & U> = never;

type TestArgCount = [
    AssertExact<number, ArgCount<(...args: any[]) => any>>,

    AssertExact<0, ArgCount<() => true>>,

    AssertExact<1, ArgCount<(x: number) => true>>,    

    AssertExact<2, ArgCount<(x: number, y: string) => true>>,

    AssertExact<1 | 2, ArgCount<(x: number, y?: string) => true>>,

    AssertExact<number, ArgCount<(x: number, ...args: any[]) => true>>,
    
    AssertExact<number, ArgCount<(x: number, y?: string, ...args: any[]) => true>>,

    AssertExact<number, ArgCount<Function>>,

    AssertExact<number, ArgCount<typeof Function>>
];

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants