dsherret / conditional-type-checks Goto Github PK
View Code? Open in Web Editor NEWTypes for testing TypeScript types.
License: MIT License
Types for testing TypeScript types.
License: MIT License
export type IsAny<T> = 0 extends (1 & T) ? true : false;
source: @material-ui/types
let a: IsAny<2>;
a
is of type boolean
here.
a
should be of type false
Typescript version: 3.0.1
It works for any
type correctly, IsAny<any>
returns true, so we can use that to distinguish further.
export type IsAny<T> = IsUnknown<T> extends true ? false
: IsNever<T> extends true ? false
: (T extends any ? any extends T ? true : false : false) extends true ? true : false;
For example:
assert<IsExact<{ other?: Date; }, { }>>(true);
...doesn't error.
Because typescript doesn't support strict version of Extract for union types. (microsoft/TypeScript#31474)
How about add constraints to type parameters of Has
?
current behavior
assert<Has<'a' | 'b', 'a'>>(true); // true.
assert<Has<'a', 'a' | 'b'>>(true); // also true. Can 'a' has 'a' | 'b' ?
assert<Has<string | number, number>>(true); // true.
assert<Has<number, string | number>>(true); // also true. Can `number` has `string` | `number` ?
Suggestion
/**
* Checks if type `T` has the specified type `U`.
*/
export declare type Has<T, U extends T> = IsAny<T> extends true ? true : IsAny<U> extends true ? false : Extract<T, U> extends never ? false : true;
assert<Has<'a' | 'b', 'a'>>(true); // true.
assert<Has<'a', 'a' | 'b'>>(true); // Type '"a" | "b"' does not satisfy the constraint '"a"'.
assert<Has<string | number, number>>(true); // true.
assert<Has<number, string | number>>(true); // Type 'string | number' does not satisfy the constraint 'number'
This passes, but it shouldn't:
assert<IsExactType<string | undefined, string>>(true);
Similar to IsExact, but less strict.
I have been trying to write an assertion that two types have an identical shape. They both contain a nested type. I can't figure out a way to check that this nested type is equal.
If I add a property to one of the outer types, it yields an error. But adding a property to one of the inner types has no effect even though it should (I believe) produce a condition of insufficient overlap. This seems incorrect. Is this a bug or am I doing something wrong?
For example:
assert<IsExact<{ prop: Date; }, { prop: any; }>>(true); // doesn't error, not great
I have been researching solutions for TS type testing such as this repo.
It seems superior to other solutions since it exposes assertion types and not only assertion methods, keeping testing very flexible.
I think that should be documented as well as:
// @ts-expect-error
)ParameterType
or another utility typeThanks for this repo!
IsExact
returns true
when the only difference between two interfaces is the readonly
modifier.
interface A {
value: string;
}
interface B {
readonly value: string;
}
assert<IsExact<A, B>>(false); // fails the compiler because `IsExact` returns `true`
I consider it as a bug.
Hi,
I can't make IsExact
work with enums.
const foo = 'Foo';
enum A {
A1 = 'A1',
A2 = 'A2',
}
export const t1 = [foo, ['A1']] as const;
export type T1 = typeof t1[number];
export type T2 = typeof foo | readonly [A.A1]
assert<IsExact<T1, T2>>(true);
In the example above
T1
is "Foo" | readonly ["A1"]
T2
is "Foo" | readonly [A.A1]
I presume the issue is that for the type system "A1"
is not exact to A.A1
Edit.
Following your another option approach (that doesn't require this library), I can see the origin of the error, which is extremely helpful.
The final type could resolve to true
or false
(so only at the end... the rest use true
or never
) and then AssertTrue
and AssertFalse
methods could be added like so:
type AssertTrue<T extends true> = T;
type AssertFalse<T extends false> = T;
Then used:
type Test = AssertTrue<IsNullableType<string>> & AssertTrue<HasType<string | number, string>>;
I guess the danger with that is people doing: AssertTrue<IsNullableType<string> & HasType<string | number, string>>
.
Anyway, I need to think this out more. I just thought of it a few mins ago and it's early for me.
// before
asserts<IsExact<T1, T2>>(true)
// after
eq<T1, T2>(true)
import { assert, IsExact } from 'conditional-type-checks';
assert<IsExact<IDBValidKey, IDBValidKey>>(true);
"Type instantiation is excessively deep and possibly infinite."
This used to work, but something in Typescript changed.
Would be nice to tell when a type has a property.
For example, I have some types that are missing a property in them that they should have so I do a cast to "any". It would be nice to leave something in the code so I get notified when the types I'm relying on get fixed to include this property (so that I can remove my any
cast).
I want to compare two interfaces and write runtime tests based on the result.
type IDialogUnchanged = IsExact<IDialog, IDialogOrig>;
I have that so far but I am unsure of how to turn that into a variable I can check at runtime.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.