Skip to content

fix(typescript): accept union types#9

Closed
callmehiphop wants to merge 1 commit intosindresorhus:masterfrom
callmehiphop:union-types
Closed

fix(typescript): accept union types#9
callmehiphop wants to merge 1 commit intosindresorhus:masterfrom
callmehiphop:union-types

Conversation

@callmehiphop
Copy link

Fixes #8

Please be gentle!

@sindresorhus
Copy link
Owner

// @BendingBender

declare function arrify<ValueType>(value: ValueType[]): ValueType[];
declare function arrify<ValueType>(value: Iterable<ValueType>): ValueType[];
declare function arrify<ValueType>(value: ValueType): [ValueType];
declare function arrify<ValueType>(value: ValueType|ValueType[]): ValueType[];
Copy link
Contributor

@BendingBender BendingBender Apr 5, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that we should rethink the whole definion. What you propose only fixes the case that the parameter is of a special type or an array of this type (number | number[]). What about number | string[] or any other type combination?

I've come up with this one, it seems to work as expected but is very ugly:

Suggested change
declare function arrify<ValueType>(value: ValueType|ValueType[]): ValueType[];
declare function arrify<ValueType>(
value: ValueType
): ValueType extends (null | undefined)
? []
: ValueType extends string
? [string]
: ValueType extends (infer T)[]
? T[]
: ValueType extends ReadonlyArray<infer T>
? ReadonlyArray<T>
: ValueType extends Iterable<infer T>
? T[]
: [ValueType];

Do you have a better idea?

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

// @ajafff

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

: ValueType extends Iterable
? [T]

[T] should be T[]

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, thank you!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@callmehiphop Could you please update your PR with the suggested changes?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm ok closing this one out if you want to open a new PR with those changes

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, close this one, I'll open a new one.

arrify(new Map<string | number, string | number>([[1, 2], ['a', 'b']]))
);
expectType<number[]>(arrify(new Set([1, 2])));
expectType<number[]>(arrify<number>(Boolean() ? [1, 2] : 3));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Following tests pass with just the proposed type above, no other overloads needed:

Suggested change
expectType<number[]>(arrify<number>(Boolean() ? [1, 2] : 3));
expectType<[]>(arrify(null));
expectType<[]>(arrify(undefined));
expectType<[string]>(arrify('🦄'));
expectType<string[]>(arrify(['🦄']));
expectType<[boolean]>(arrify(true));
expectType<[number]>(arrify(1));
expectType<[{}]>(arrify({}));
expectType<([string | number, string | number])[]>(
arrify(new Map<string | number, string | number>([[1, 2], ['a', 'b']]))
);
expectType<number[]>(arrify(new Set([1, 2])));
expectError(arrify(['🦄'] as const).push(''));
expectType<number[] | []>(arrify(Boolean() ? [1, 2] : null));
expectType<number[] | []>(arrify(Boolean() ? [1, 2] : undefined));
expectType<number[] | [string]>(arrify(Boolean() ? [1, 2] : '🦄'));
expectType<number[] | string[]>(arrify(Boolean() ? [1, 2] : ['🦄']));
expectType<number[] | [boolean]>(arrify(Boolean() ? [1, 2] : true));
expectType<number[] | [number]>(arrify(Boolean() ? [1, 2] : 3));
expectType<number[] | [{}]>(arrify(Boolean() ? [1, 2] : {}));
expectType<number[] | (string | boolean)[]>(
arrify(Boolean() ? [1, 2] : new Set<string | boolean>(['🦄', true]))
);
expectType<number[] | [boolean] | [string]>(
arrify(Boolean() ? [1, 2] : Boolean() ? true : '🦄')
);

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

Successfully merging this pull request may close these issues.

4 participants