You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Summary:
I can define in typescript that tuple contains optional elements, e.g. let array: [string?]; - I can assign empty array. But can I combine this with conditional (generic) type: when type is defined then value should be set. Otherwise, value is disallowed. Or at least optional if not disallowed.
TypeScript Version:
3.5.0-dev.20190515
Search Terms:
tuple with conditional optional type
Code
interfaceA<T=never>{array: [[T]extends[never] ? never : T,// how to make this `never` as optional?// smth like this does not work:// [T] extends [void] ? never? : T1, //error: `JSDoc types can only be used inside of documentation comments`// T? // optional works here correctly]}lettest1: A<string>;test1.array=["some string"]test1.array=[]// error: correctlylettest2: A;test2.array=[""]// error: correctlytest2.array=[undefined]// error: correctlytest2.array=[null]// error: correctlytest2.array=[];// error: INCORRECTLY! `Property '0' is missing in type '[]' but required in type '[never]'.`
Expected behavior:
I can assign empty array to test2.array. Even more - I cannot assign not empty array.
Actual behavior:
I cannot assign empty array. I cannot assign also array with some value. I have to use some other type and pass it explicitly, e.g. undefined:
interfaceA<T=never>{array: [[T]extends[never] ? undefined : T]}lettest1: A<string>;test1.array=["some string"]test1.array=[]// error: correctlylettest2: A;test2.array=[""]// error: correctlytest2.array=[undefined]// error: correctlytest2.array=[null]// no error: is it correct?test2.array=[];// error: INCORRECTLY! `Property '0' is missing in type '[]' but required in type '[never]'.`
OK, it works. There are more generic types and first one can be defined and second one omitted (and more types). But your response apply also to this.
interfaceA<T1=never,T2=never>{array: [T1]extends[never]// if T1 is not defined, then T2 is also not defined by sure
? []
: [T2]extends[never]
? [T1]
: [T1,T2]}lettest1: A<string>;test1.array=["some string"]test1.array=[]// error: correctlylettest2: A;test2.array=[""]// error: correctlytest2.array=[undefined]// error: correctlytest2.array=[null]// error: correctlytest2.array=[];lettest3: A<string,number>;test3.array=["some string",55]test3.array=[]// error: correctly
I've encountered another problem with new solution - I need to call reduce on array to create string (T1 and T2 extends string keys of another class - so it should be possible).
Simplified code:
classGenericTupple<T1,T2>{tupple: [T1]|[T1,T2];getString(){// This one does not work :/// error: `Type 'string' is not assignable to type 'T1'.returnthis.tupple.reduce((final,prev)=>`${final}.${prev}`,'');}}
This results from original code (from comment above) with conditional types (so I cannot define tupple as: tupple: [T1, T2?];:
classA<T1,T2=never,T3=never>{array: [T2]extends[never]
? [T1]
: [T3]extends[never]
? [T1,T2]
: [T1,T2,T3]getString(): string{// error: `Type 'string' is not assignable to type 'T1'.`returnthis.array.reduce((final,prev)=>`${final}.${prev}`,'');}}
Is it possible without casting? As I can see, incorrect reduce is detected: reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue: T): T;
instead of reduce<U>(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U;
Should I create new issue (this is connected a little with original question so for now I opened this one - am I missing something obvious)?
Activity
AlCalzone commentedon May 15, 2019
works
Krzyrok commentedon May 15, 2019
OK, it works. There are more generic types and first one can be defined and second one omitted (and more types). But your response apply also to this.
playground
This below looks better but I'm happy that above one is working
Thanks a lot!
Krzyrok commentedon May 16, 2019
I've encountered another problem with new solution - I need to call
reduceonarrayto createstring(T1andT2extends string keys of another class - so it should be possible).Simplified code:
playground
casting helps:
This results from original code (from comment above) with conditional types (so I cannot define tupple as:
tupple: [T1, T2?];:playground
Is it possible without casting? As I can see, incorrect
reduceis detected:reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue: T): T;instead of
reduce<U>(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U;Should I create new issue (this is connected a little with original question so for now I opened this one - am I missing something obvious)?