Assume you have a code, which cannot be changed:
<code>type TProps<TK extends string, T> = { a: TK; b: T };
</code>
<code>type TProps<TK extends string, T> = { a: TK; b: T };
</code>
type TProps<TK extends string, T> = { a: TK; b: T };
i am need to make wrapper type for it, which set TK
at root, and T
for field level:
<code>type TWrap<TR> = {
func: <T>() => TProps<TR, T>;
}
</code>
<code>type TWrap<TR> = {
func: <T>() => TProps<TR, T>;
}
</code>
type TWrap<TR> = {
func: <T>() => TProps<TR, T>;
}
wrapped to function, because ts cannot allow to add generic argument to type fields.
tried to write code, but still cannot get solution (key rows is marked with comments 1 and 2):
<code>type tf<R> = () => R;
type to<A1,A2> = {};
type TSetTypeArgument<T, A> = T extends tf<infer R>
? R extends to<infer X, infer Y> // 1
? to<X, A> & R // 2
: never
: never;
type TRes = TSetTypeArgument<TWrap['func'], number>;
</code>
<code>type tf<R> = () => R;
type to<A1,A2> = {};
type TSetTypeArgument<T, A> = T extends tf<infer R>
? R extends to<infer X, infer Y> // 1
? to<X, A> & R // 2
: never
: never;
type TRes = TSetTypeArgument<TWrap['func'], number>;
</code>
type tf<R> = () => R;
type to<A1,A2> = {};
type TSetTypeArgument<T, A> = T extends tf<infer R>
? R extends to<infer X, infer Y> // 1
? to<X, A> & R // 2
: never
: never;
type TRes = TSetTypeArgument<TWrap['func'], number>;
and test it:
<code>const t3: TRes = { a: '', b: 7 };
// `b` must be number
const b = t3.b;
// but now `b` is `unknown`
</code>
<code>const t3: TRes = { a: '', b: 7 };
// `b` must be number
const b = t3.b;
// but now `b` is `unknown`
</code>
const t3: TRes = { a: '', b: 7 };
// `b` must be number
const b = t3.b;
// but now `b` is `unknown`
It is possible TSetTypeArgument
type to get variable b
typed as number?
playground link