Closed goodmind closed 7 years ago
Tried for a bit, here's what I came up with:
export type Obj<T> = { [k: string]: T };
export type UnionHasKey<Union extends string, K extends string> = ({[S in Union]: '1' } & Obj<'0'>)[K];
export type If<Cond extends '0'|'1', Then, Else> = { 1: Then, 0: Else }[Cond];
type A = { a: 'b', c: 'd' };
type Keys = keyof A; // "a" | "c"
type Vals = A[keyof A]; // "b" | "d"
type y = {[P1 in Vals]: {[P2 in keyof A]: If<UnionHasKey<A[P2], P1>, P2, never> }[Keys] }; // { b: "a"; d: "c"; }
type Swap<
T extends { [k: string]: string },
Keys extends keyof T = keyof T,
Vals extends string = T[Keys]
> = {[P1 in Vals]: {[P2 in Keys]: If<UnionHasKey<T[P2], P1>, P2, never> }[Keys]};
type B = Swap<A>;
Still fails in playground, though I think master should have fixed most issues like this. Haven't managed to test that way yet, but yeah.
@tycho01 wow, still trying to figure out how things in this repo ever works
Haha :), I just try step by step too, but yeah, it looks more complex when put together. To sorta illustrate what's going on:
UnionHasKey<A[P2], P1>
is just a fancy type version of an equality check (P1 == A[P2]
).never
'b' | never
), all the never
s automatically get scrubbed outNice one! :)
I kinda gave up after
type strT = {
[key: string]: string
}
type Swap<T extends strT> = {
[N in T[keyof T]]: ???
}
type A = { a: 'b', c: 'd' }
type B = Swap<A>
Do you know how to write type like this one?