TypeScript/tests/baselines/reference/recursiveConditionalCrash3.js

166 lines
4.8 KiB
TypeScript

//// [recursiveConditionalCrash3.ts]
// #43529
export {}
/**
*
* Some helper Types and Interfaces..
*
*/
export type CanBeExpanded<T extends object = object, D = string> = {
value: T
default: D
}
interface Base {
}
interface User extends Base {
id: string,
role: CanBeExpanded<Role>,
note: string,
}
interface Role extends Base {
id: string,
user: CanBeExpanded<User>,
x: string
}
// This interface will be expanded in circular way.
interface X extends Base {
id: string,
name: string,
user: CanBeExpanded<User>,
role: CanBeExpanded<Role>
roles: CanBeExpanded<Role[]>
}
type Join<K, P> = K extends string | number ?
P extends string | number ?
`${K}${"" extends P ? "" : "."}${P}`
: never : never;
type PrefixWith<P, S, C = '.'> = P extends '' ? `${string & S}` : `${string & P}${string & C}${string & S}`
type SplitWithAllPossibleCombinations<S extends string, D extends string> =
string extends S ? string :
S extends '' ? '' :
S extends `${infer T}${D}${infer U}` ?
T | Join<T, SplitWithAllPossibleCombinations<U, D>>
: S;
/**
* This function will return all possibile keys that can be expanded on T, only to the N deep level
*/
type KeysCanBeExpanded_<T, N extends number, Depth extends number[]> = N extends Depth['length'] ? never :
T extends CanBeExpanded ?
KeysCanBeExpanded_<T['value'], N, Depth> :
T extends Array<infer U> ? KeysCanBeExpanded_<U, N, Depth> :
T extends object ?
{
[K in keyof T ] :
T[K] extends object ?
K extends string | number
? `${K}` | Join<`${K}`, KeysCanBeExpanded_<T[K], N, [1, ...Depth]>>
: never
: never
}[keyof T]
:
never
export type KeysCanBeExpanded<T, N extends number = 4> = KeysCanBeExpanded_<T, N, []>
/**
* Expand keys on `O` based on `Keys` parameter.
*/
type Expand__<O, Keys, P extends string, N extends number , Depth extends unknown[] > =
N extends Depth['length'] ?
O extends CanBeExpanded ?
O['default'] :
O :
O extends CanBeExpanded ?
Expand__<O[P extends Keys ? 'value' : 'default'], Keys, P, N, Depth> :
O extends Array<infer U> ?
Expand__<U, Keys, P, N, Depth>[]
: O extends object ?
{
[K in keyof O]-?: Expand__<O[K], Keys, PrefixWith<P, K>, N, [1, ...Depth]>
}
: O
type SplitAC<K> = SplitWithAllPossibleCombinations<K extends string ? K : '', '.'> extends infer Ko ? Ko : ''
type Expand_<T, K, N extends number = 4> = Expand__<T, SplitAC<K>, '', N, []>
type AllKeys<T, N extends number = 4> = KeysCanBeExpanded<T, N> extends infer R ? R : never
/**
* If I open the popup, (pointing with the mouse on the Expand), the compiler shows the type Expand, expanded as expected.
*
* It's fast and it doesn't use additional memory
*
*/
export type Expand<T extends object, K extends AllKeys<T, N> = never, N extends number = 4> = Expand_<T, K, N>
/**
* These two functions work as charm, also they are superfast and as expected they don't use additional Memory
*/
let y1: Expand<X>
let y2: Expand<X, 'user.role.user.role'>
/**
*
* ... nevertheless when I need to use the Expand in other Types, as the following examples, the popup show "loading..." and without show any information and
* the Memory Heap grows to 1.2gb (in my case) every time... You can see it opening the Chrome DevTools and check the memory Tab.
*
* *******
* I think this is causing "FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory"
* on my project during the `yarn start`.
* *******
*
*/
type UseQueryOptions<T extends Base, K extends AllKeys<T, 4> > = Expand<T, K>
type UseQueryOptions2<T , K > = Expand_<T, K>
type UseQueryOptions3<T , K > = Expand_<T, K> extends infer O ? O : never
type ExpandResult<T,K> = Expand_<T, K> extends infer O ? O : never
type UseQueryOptions4<T , K > = ExpandResult<T,K>
/**
* but as you can see here, the expansion of Interface X it's still working.
*
* If a memory is still high, it may need some seconds to show popup.
*
*/
let t: UseQueryOptions<X, 'role.user.role'>
//// [recursiveConditionalCrash3.js]
"use strict";
// #43529
exports.__esModule = true;
/**
* These two functions work as charm, also they are superfast and as expected they don't use additional Memory
*/
var y1;
var y2;
/**
* but as you can see here, the expansion of Interface X it's still working.
*
* If a memory is still high, it may need some seconds to show popup.
*
*/
var t;