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

Type compatibility/can assign #349

Open
carloszimm opened this issue Aug 15, 2023 · 5 comments
Open

Type compatibility/can assign #349

carloszimm opened this issue Aug 15, 2023 · 5 comments
Labels
breaking change bug Something isn't working

Comments

@carloszimm
Copy link

Forgive me if I have understood wrong (the functionality) but the following code shouldn't work without compiler problems?

assertType.isTrue(true as CanAssign<any, number>);

If the order is inverted, it works fine. Also, the following code apparently compiles:

let a: any = 4;
let b: number = a;

let d: number = 3;
let e: any = d;

StackBlitz print:
image

Thank you :)

@unional unional added bug Something isn't working breaking change labels Aug 15, 2023
@unional
Copy link
Owner

unional commented Aug 15, 2023

Hi, yes, you are technically correct. TypeScript has some weird behavior around any.

Besides meaning any type, or union of all types, or the superset of all types, any is also used as a "type checking silencer", allowing user to tell the compiler that "hey, don't worry about the type of this".

That's why you can do const x: number = 'a' as any.

The CanAssign<A, B> type was checking more like on the set theory, which any cannot assign to number.

In fact, the CanAssign<any, number> should really return boolean, instead of false, as "some branch in the union (of any) can be assigned to number, while some cannot".

This type will be updated in the near future, but it will be a breaking change.

@carloszimm
Copy link
Author

The CanAssign<A, B> type was checking more like on the set theory, which any cannot assign to number.

As I suspected 😅
Anyway, while the update doesn't come up, a possible workaround can be to check if either operand is the type any, so there will be no need to proceed with the type checking. Also, it seems to be working properly when incorporated inside a class for instance (so the workaround should work):
image

@unional
Copy link
Owner

unional commented Aug 16, 2023

Yes. The IsAny check can be applied. Many of the newer types such as IsEqual is doing that kind of checks.

CanAssign can be improved with that too.

For the inside a class/object, yes. That's the original purpose of the type and that is handled differently.

I'm working on a new way to handle branching to maximize flexibility. CanAsssign can use some updates when I get to it.

btw, if you want to check for CanAssign between two types, you can do testType.canAssign<A,B>(true | false).

@carloszimm
Copy link
Author

I wasn't aware that testType had a canAssign (the documentation apparently didn't mention it yet). Anyway, is it supposed to behave similarly to assertType (with the compiler complaining about the wrong type) or it should return only a boolean? If the later, why the following snippet is complaining? :(
image

Btw, I suppose testType is one of the types you mentioned that is making those checks, as it works correctly for the following test:

console.log(testType.canAssign<number, any>(true)); //--> true
console.log(testType.canAssign<any, number>(true)); //--> true

@unional
Copy link
Owner

unional commented Aug 17, 2023

I wasn't aware that testType had a canAssign (the documentation apparently didn't mention it yet).

Um, thanks for pointing it out. I thought I have the doc updated. Seems like I have missed it.

It is in the docs under the /testing folder,
and it has JSDocs and unit tests describing each function.

It is mainly for used during testing. The return value is merely a container of the type under inspection, as all the check are done with pure type anyway (the same for assertType.isTrue(true ...), the return value can only be true 😄 )

For runtime check, currently the canAssign<T>(): (subject: S) => CanAssign<S, T> is the one you can use.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
breaking change bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants