Identity Functions 5 exercises
solution

Fix Inference Issues with F.NoInfer

The solution here is to use F.NoInfer on the initial state:


interface FSMConfig<TState extends string> {
initial: F.NoInfer<TState>;
states: Record<
TState,
{
onEntry?: () => void;
}
>;
}

Adding NoInfer prevents anything you put in that initial spot fr

Loading solution

Transcript

0:00 The solution here is to use F.NoInfer on this initial state. What this does, F.NoInfer state, is it means that anything you put in that initial spot won't be inferred from. If I add like d here, then this isn't going to make its way into the type argument. It's not going to be inferred from. Only a and b are available.

0:24 TypeScript itself has a kind of internal hierarchy of which parts it pays attention to for inference. If you had, for instance, a type...Let's say we had const func. Let's say we have T. Then we have a, which is going to be T, and b, which is going to be T. In fact, a great example of this is a compare function. We can return a == b, like this.

0:52 Now what we can do is we can say, let's say, "compare." We'll go 2 and 123, like this. Let me restart my TS server, because for some reason it needs to. Now it's going to error at me because argument of type number is not assignable to parameter of type number.

1:08 That's because TypeScript is choosing to look at this first one as its favorite. That's the one it's inferring from. If I actually go F.NoInfer here, it's now going to choose the second one as the thing to infer from. How silly is that? There we go. It's now being captured as number, but with F.NoInfer in the first one, then it grabs string there.

1:33 No idea what's going to happen, but let's try putting F.NoInfer on both of them. There we go. Now it won't infer from either of those sites, so it defaults to unknown. Really interesting. This is what F.NoInfer is used for. It's used for little, niche use cases.

1:49 Unlike F.Narrow, there isn't a solution coming yet to TypeScript to solve this. F.NoInfer, which looks like this, by the way, it's pretty simple to copy into your project. My God, it's complicated. I'm not entirely sure why this works. Maybe a wizard out there can figure it out and comment in Discord.

2:09 It's a useful bit of kit for when you have multiple inference sites and you want to guide TypeScript to the one that you prefer.