-
Notifications
You must be signed in to change notification settings - Fork 12.5k
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
Suggestion: Type-check statement to verify type assignability #30809
Comments
This should be covered by #23689 |
This is already possible to do with conditional types. See here: https://stackoverflow.com/a/55046618/188246 (Rolled up in my poorly named library here). // or use AssertTrue type alias
import { Has, assert } from "conditional-type-checks";
import { SomeType } from "some-external";
assert<Has<SomeType, WantedType>>(true); |
Thanks for comments. In my suggestion, both calling function and unused type definition are not necessary. |
@jet2jet it's possible to not use any runtime code... import { Has, AssertTrue } from "conditional-type-checks";
type _doTests = AssertTrue<Has<SomeType, WantedType>>; ...but yeah, that creates the problem with the unused local. To solve that, I think the TypeScript's type checker should probably be changed to not throw an unused local error when the type alias is prefixed with an underscore similar to its behaviour with parameters (alternatively, you could just add an Conditional types are very flexible for doing many things today. For example, it's possible to check if a type is exactly the same as another type (ex. ensuring type A is exactly the same as type B.... where type A is Do you think this new syntax should also support using conditional types somehow? Or would it be possible to say that one type should exactly equal another (not just extends)? |
Yes,
I think it would not be possible; when both |
This would be invaluable for validating more complicated type-level programming. I'm already commonly doing |
Definitely want this; I’ve worked around this kind of thing in my code a lot, and the workarounds are a pain. This most recently came up in discussion of #13298, where I had a couple of suggestions for achieving the same compile-time check that the suggestion was trying to get at: here and here. But both approaches have drawbacks, when what I really want to write is: export type TheUnion = 'foo' | 'bar';
/** A correct tuple, in the same order as the union */
export const validTuple = ['foo', 'bar'] as const;
assert type typeof validTuple extends SetTuple<typeof validTuple>; // no error
assert type typeof validTuple extends readonly TheUnion[]; // no error
assert type typeof TheUnion extends typeof validTuple[number]; // no error
/** A correct tuple, in the opposite order as the union (doesn't matter) */
export const alsoValidTuple = ['bar', 'foo'] as const;
assert type typeof alsoValidTuple extends SetTuple<typeof alsoValidTuple>; // no error
assert type typeof alsoValidTuple extends readonly TheUnion[]; // no error
assert type TheUnion extends typeof alsoValidTuple[number]; // no error
/** A wrong tuple, for several reasons */
export const invalidTuple = ['bar', 'bar', 'baz'] as const;
type assert typeof invalidTuple extends SetTuple<typeof invalidTuple>;
^^^^^^
Type 'readonly ["bar", "bar", "baz"]' is not assignable to type 'readonly ["bar", "baz"]'.
Source has 3 element(s) but target allows only 2. ts(2322)
type assert typeof invalidTuple extends readonly TheUnion[];
^^^^^^
Type 'readonly ["bar", "bar", "baz"]' is not assignable to type 'readonly ("foo" | "bar")[]'.
Type '"bar" | "baz"' is not assignable to type '"foo" | "bar"'.
Type '"baz"' is not assignable to type '"foo" | "bar"'. ts(2322)
type assert TheUnion extends typeof invalidTuple[number];
^^^^^^
Type '"foo" | "bar"' is not assignable to type '"bar" | "baz"'.
Type '"foo"' is not assignable to type '"bar" | "baz"'. ts(2322) |
Search Terms
type check statement compile (compilation) time
Suggestion
I wanted to check compatibilities for types from different (especially external) modules in compilation time.
To solve it, I suggest to add type-check statement like following:
type
statement, but the above statements are not conflicted becausetype
statements requires=
after BindingIdentifier (or TypeParameters).type assert
only check types; it does not cast variables.extends
keyword may confuse to one used in conditional type. (not ambiguous?)type assert A extends B
, bothA
andB
should accept conditional type.type assert
is somewhat inspired by other languages'assert
statements (especiallystatic_assert
in C/C++), but I don't know whether the wordstype assert
are the best...)Use Cases
Currently we can check types statically as following:
While no JavaScript codes are generated from this code, this is more complex to check.
Examples
Checklist
My suggestion meets these guidelines:
The text was updated successfully, but these errors were encountered: