Acid Coder

type A = {[x:string]:string} 
type B = keyof A // string | number
// ^?
const A:A = {a:"abc",[1]:"xyz"}type C = keyof A & string // string
// ^?

playground

normally this will not cause any issue, because number key in javascript will coerce into string key

however this may cause issue if we are doing some type manipulation

to solve this we can intersect it with string or set keyofStringsOnly to true in the ts config

or just use Record<string, T> or{[x in string]: T}

this is work as expected

more on github PR and release note

--

--

In the last post we know multiplication is possible

In this post we are going to try division

type CreateArrayWithLengthX<
LENGTH extends number,
ACC extends unknown[] = [],
> = ACC['length'] extends LENGTH
? ACC
: CreateArrayWithLengthX<LENGTH, [...ACC,1]>
type Division<Dividend extends number, Divisor extends number, ACC extends unknown[] = [], Counter extends unknown[] = []> =
[...ACC,...CreateArrayWithLengthX<Divisor>]['length'] extends [...CreateArrayWithLengthX<Dividend>]['length']
? [1,...Counter]['length']
: Division<Dividend, Divisor, [...ACC,...CreateArrayWithLengthX<Divisor>],[1,...Counter]>
type result = Division<999, 3> // 333

playground

limitation: the dividend cannot exceed 999 because the max depth of TS recursion is only 1000, only work with positive integer. the divisor must be factors of the dividend

--

--

We have seen how can we add two numeric literals type

now can we apply similar tricks for subtraction?

yes we can, this is how we do it:

type CreateArrayWithLengthX<
LENGTH extends number,
ACC extends unknown[] = [],
> = ACC['length'] extends LENGTH
? ACC
: CreateArrayWithLengthX<LENGTH, [...ACC,1]>

type Subtraction<LARGER extends number, SMALLER extends number, GAP extends number[] = []> =
[...GAP,...CreateArrayWithLengthX<SMALLER>]['length'] extends [...CreateArrayWithLengthX<LARGER>]['length']
? GAP['length']
: Subtraction<LARGER, SMALLER, [1,...GAP]>

type result = Subtraction<849, 654> // 195

playground

limitation: the number cannot exceed 999 because the max depth of TS recursion is only 1000, only work with positive integer

--

--

here is how you do it

type TupleToArray<
T extends unknown[],
Acc = never
> = T extends [infer H, ...infer Rest]
? Rest extends []
? (H | Acc)[]
: TupleToArray<Rest, Acc | H>
: "impossible route"
type A = TupleToArray<[number, string, boolean]> // (string | number | boolean)[]

--

--