GithubHelp home page GithubHelp logo

type-zoo's People

Contributors

dalegaard avatar dependabot[bot] avatar ekilah avatar fbartho avatar marcind avatar pelotom avatar seansfkelley avatar ssonne avatar uselesspickles avatar wkovacs64 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

type-zoo's Issues

Overlapping string unions

Hi, love the project!

Would you consider adding a type for overlapping string unions? It should be implementable directly based on the existing Diff:

type Overlap<T extends string, U extends string> = Diff<T, Diff<T, U>>;

I'm not sure what would be the best name for the thing, but Overlap seems descriptive and in line with the existing types in this library.

Best regards!

Interest in `ExtractStrict`?

Any interest / reason to not want this type added? I can make a PR if so:

type ExtractStrict<T, U extends T> = T extends U ? T : never

context:

Seems like the TS team's reasoning for making their official Omit non-strict included the fact that Extract was also non-strict, which is something I just ran into wanting. Just like OmitStrict, ExtractStrict will get the compiler to help out during refactoring things like this, or to prevent typos in the string keys:

export type TSomeColorOptions = ExtractStrict<TColor, 'blue' | 'whitee'> // should error for typo

Useless NoInfer

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

Overwrite is not homomorphic

Using TypeScript 2.6.2, I have encountered an issue with Overwrite not being homomorphic.

Example:

export type Overwrite<T, U> = { [P in Diff<keyof T, keyof U>]: T[P] } & U;

interface A {
    foo?: number;
    bar?: number;
}

interface B {
    bar?: string;
    baz?: string;
}

type C = Overwrite<A, B>;

// error TS2322: Type '{ bar: string; }' is not assignable to type 'Overwrite<A, B>'.
//  Type '{ bar: string; }' is not assignable to type '{ foo: number | undefined; }'.
//    Property 'foo' is missing in type '{ bar: string; }'.
const c: C = {
    bar: "hello"
};

I have solved this by rewriting Overwrite as:

export type Overwrite<T, U> = Omit<T, Diff<keyof T, Diff<keyof T, keyof U>>> & U;

Breaking it down:

  • Diff<keyof T, keyof U> gives us all keys in T that are not in U. Let's call this NotInU.
  • Diff<keyof T, NotInU> gives us all keys that are in both T and U. Let's call this InBoth.
  • Omit<T, InBoth> gives us a type that contains only the properties that are unique to T (omits all properties that also exist in U).
  • Finally, tack on the & U to include ALL properties from U

ParamTypes issue

As I mentioned in microsoft/TypeScript#25660 (comment) and in microsoft/TypeScript#21316 (comment)
without inversed check you got wrong result

declare function argTypes<F extends Function>(f: F): ParamTypes<F>

// $ExpectType []
argTypes(() => true); // Expected type to be:  [] got:  {}

// $ExpectType [string, boolean | undefined]
argTypes((x: string, y?: boolean) => true); // Expected type to be:  [string, boolean | undefined] got:  [string]

Match

Hello. Someone just creating an overlapping library - https://github.com/danielpa9708/ts-types-utils - that has 3 types. 2 are duplicates:

  • ArgsType === ParamTypes
  • Assign === Overwrite

Match - https://github.com/danielpa9708/ts-types-utils#match looks quite useful

type FunctionProperties<T> = Match<T, Function>;

is easier to formulate than

type FunctionPropNames<T> = { [K in keyof T]: T[K] extends Function ? K : never }[keyof T];
type FunctionProperties<T> = Pick<T, FunctionPropNames<T>>;

Of course, just lifting it from https://github.com/danielpa9708/ts-types-utils wouldn't be cool, but maybe reach out to the author to consolidate?

Edit

It looks like @danielpa9708's ArgsType could be an improvement on ParamTypes - it looks to be able to work for any number of parameters, and ArgsType[N] === ParamN for any N....

Required<T> broken with Typescript 2.9

Now that Typescript produces something assignable to string | number | symbol for keyof T, the definition of Required yields this error:

Type 'keyof T' does not satisfy the constraint 'string'.
  Type 'string | number | symbol' is not assignable to type 'string'.
    Type 'number' is not assignable to type 'string'.

46   [P in Purify<keyof T>]: NonNullable<T[P]>;

Projects using type-zoo could use the "keyofStringsOnly": true compiler option as a workaround for the time being.

Longer term, the definition of Purify could be updated to export type Purify<T extends string | number | symbol> = { [P in T]: T; }[T];, however this is a breaking change for previous versions of TypeScript.

An alternative would be to declare something like type Purify2<O, T extends keyof O> = { [P in T]: T; }[T]; and have Required<T> use that instead.

Thoughts? I can send a PR.

Falsy

export type Falsy = false | null | undefined | 0 | ''

export const isTruthy = <T>(val: T): val is Exclude<T, Falsy> => !!val

add DeepPartial<T>

Could this be added?

type DeepPartial<T> = {
  [P in keyof T]?: DeepPartial<T[P]>;
};

Wanted to check here first before creating a pull request...

Idea for type to convert all children of an object to be a particular type

I'm starting to use this a fair bit for example when getting data from a datastore where all the values are strings. They don't necessarily fit the nicely typed structure I have for my model, but I don't want to have to explicitly write out a new type just for the version which is all strings coming back from the data store:

export type Monotype<T, U> = {[K in keyof T] : U}

Duplication of types included in the standard library

The idea is that these types will hopefully make their way into the language proper, at which point you can simply stop importing them from type-zoo and be on your merry way.

Some of the types implemented here have been implemented in TypeScript's standard library, e.g.:

Since the versions implemented here are redundant, and in some cases more limited, I would suggest either aliasing them to the stdlib version, or documenting the supported TypeScript version and removing them.

Intersection types and Omit

Hi,

I'm fairly deep into my recent need to understand/learn Typescript's type system, and am using type-zoo as well. I've run into an issue with Omit that I don't understand, so I've made an example here to ask you about it:

typescript playground link

here's the code (same as in the playground above):

// This is the definition of Omit from type-zoo
type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>

type Foo = {
    x?: string
    willOmitThis?: any
}

type Bar = {
    y?: number
    willOmitThis?: any
}

// ----------
// below, trying different ways to define a new Bar.
// in this version, we want to omit something and add something.
// ----------

type NewBarOmit = Omit<Bar, 'willOmitThis'> & {
  addedToBar?: string[]
}

type NewBar = {
    y?: number
    addedToBar?: string[]
}

// -----------


// -----------
// here, trying different ways to define a new Foo.
// in this version, we want to omit something and add something.
// the `Omit` version doesn't cause the expected type-system error 
// when a non-specified key is provided, the other version does.
// -----------

type NewFooOmit = Omit<Foo, 'willOmitThis'> & {
  addedToFoo?: NewBar // or NewBarOmit, doesn't matter
}

type NewFoo = {
  x?: string
  addedToFoo?: NewBar // or NewBarOmit, doesn't matter
}

// -----------

/* `x: NewFoo` fails correctly, `x: NewFooOmit` doesn't fail, though it should? */
const x: NewFoo = {
    addedToFoo: {
        addedToBar: ['test'],
        somethingElse: 'doesnt fail when x is of type NewFooOmit, why?',
    },
    // baz: 'fails in all cases when included, as expected',
}

I don't understand why the type system doesn't care that somethingElse is not an allowed key of the object with type NewBar if I defined NewBar with Omit.

Is this something about intersection types (the use of the & after the Omit) that I don't understand correctly? Or maybe something else, or an issue with Omit perhaps? My understanding of intersection types is that the & just combines two type definitions together to create a new type, but that doesn't seem to be correct.

(Sorry if this turns out to not be an question specific to type-zoo and instead about TS, but I wasn't sure).

thanks!

Omit and union types

Currently, if a union type is given to Omit, the returned type does not correctly preserve the union type, e.g. this test fails:

declare const foo: Omit<{ shared: string; } & ({ x: boolean } | { y: string }), 'shared'>;

/* $ExpectType Pick<{
    shared: string;
} & {
    x: boolean;
}, "x"> | Pick<{
    shared: string;
} & {
    y: string;
}, "y"> */
foo;

foo instead has type

Pick<({
    shared: string;
} & {
    x: boolean;
}) | ({
    shared: string;
} & {
    y: string;
}), never>

We can use conditional types to fix this:

export type Omit<T, K extends keyof any> = T extends any ? Pick<T, Exclude<keyof T, K>> : never;

microsoft/TypeScript#12215 (comment)

We might also want to apply this fix to some of the other helpers?

Idea: Type Unpackers for Function Parameters

Because of TypeScript 2.8 Conditional Types, we can now do the following:

type Param0<Func> = Func extends (a: infer T, ...args: any[]) => any
	? T
	: never;
type T0 = Param0<() => void>; // {}
type T1 = Param0<(a: number) => void>; // number
type T2 = Param0<(a: string[]) => void>; // string[]

Issue for discussion!

Questions:

  • Naming scheme?
  • Multiple Parameter Unpacks at the same time?

See also ReturnType<Func>

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.