Skip to content

[TS 4.1] Array.isArray incorrectly infers recursive type #41609

Description

TypeScript Version: 4.1.2

Code

I have this recursive type that I use for form generation.

exporttypeFormStructure<TFormextendsObjectLiteral>={[TKeyinkeyofTForm]?: TForm[TKey]extendsDefaultFieldStruture
? TForm[TKey]
: TForm[TKey]extendsArray<any>
? FormStructure<UnArray<TForm[TKey]>>[]
: FormStructure<TForm[TKey]>;};

And inside a recursive function, I traverse this big nested object

declareconstfields: FormStructure<TForm>return(Object.entries(fields)as[string,DefaultFieldStruture|FormStructure<TForm>][]).reduce<TReturn>((acc,[key,field])=>{if(fieldinstanceofDefaultFieldStruture){//}elseif(Array.isArray(field)&&Array.isArray(datas[key])){acc[key]=field.map((element,index)=>{// ^^^^// This expression is not callable.// Each member of the union type '(<U>(callbackfn: (value: any, index: number, array: any[]) => U, thisArg?: any) => U[]) | //(<U>(callbackfn: (value: any, index: number, array: readonly any[]) => U, thisArg?: any) => U[])' has signatures, but none // of those signatures are compatible with each other.returnmapAndCompareThroughData(element,datas[key]?.[index],predicate);}).filter((result)=>!!result);}}returnacc;},{}asTReturn);

Expected behavior:

Before passing into Array.isArray, my field var is correctly infered as

varfield: FormStructure<TForm>

After passing thought Array.isArray, it is now

varfield: FormStructure<TForm>&(FormStructure<TForm>extendsreadonlyany[] ? unknownextendsreadonlyany[]&FormStructure<TForm> ? never : readonlyany[] : any[])

I've tried puting a -readonly to my type but without success

exporttypeFormStructure<TFormextendsObjectLiteral>={-readonly[TKeyinkeyofTForm]?: TForm[TKey]extendsDefaultFieldStruture
? TForm[TKey]
: TForm[TKey]extendsArray<any>
? FormStructure<UnArray<TForm[TKey]>>[]
: FormStructure<TForm[TKey]>;};

Is there a way to make a type guard for this? Why Array.isArray became so strange to analyse?

Playground Link:https://www.typescriptlang.org/play?ts=4.1.0-beta#

The playground exemple doesn't works because TS 4.1-beta don't includes isArray new types

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions