Here's my code and the related playground:
type SomeType<T> = {
[K in keyof T]?: K extends 'u'
? string
: T[K] extends object
? SomeType<T[K]>
: object
}
function someType<T>(t: SomeType<T>) {
return t;
}
type BLA = SomeType<{
u: 1,
b: {
u: 1,
},
}>;
const blaBLA: BLA = {
u: 1, // <-- correct error msg: Type 'number' is not assignable to type 'string'.
b: {
u: 1, // <-- correct error msg: Type 'number' is not assignable to type 'string'.
},
};
const bla = someType({
u: 1, // <-- correct error msg: Type 'number' is not assignable to type 'string'.
b: {
u: 1, // <-- expected: error message from above
// the problem here is that the value for b was resolved to 'object' instead of 'SomeType<T[K]>'
// how can I fix this?
},
});
I am either looking for a fix to the problem which I describe in the code above or an explaination why it doesn't work the way I think it works.
As this is purely for learning (understanding) TS, I would be okay with either outcome.
func<T>(x: F<T>):voidand callf(x)then the compiler is going to takexas typeF<T>and try to inferTfrom it. IfF<T>is complicated enough, this is going to fail. Instead it looks like you really wantfunc<T extends F<T>>(x: T): void, whereTis easily inferred fromx, and then just checked againstF<T>, like this. Does that meet your needs (and I could write up an answer) or am I missing something?someType({ ... }). This is just a side note. I may ask a seperate question and link it here but I am still "investigating" with my limited skills.someType(...)is correct. See question.