Identity Functions 5 exercises
solution

# Using const type parameters For Better Inferenceself.__wrap_balancer=(t,e,n)=>{n=n||document.querySelector(`[data-br="\${t}"]`);let o=n.parentElement,r=E=>n.style.maxWidth=E+"px";n.style.maxWidth="";let i=o.clientWidth,s=o.clientHeight,c=i/2,u=i,d;if(i){for(;c+1<u;)d=~~((c+u)/2),r(d),o.clientHeight==s?u=d:c=d;r(u*e+i*(1-e))}};self.__wrap_balancer(":Rhd9j6:",1)

The solution here is to annotate the type parameters `T` with `const`.

`export const asConst = <const T>(t: T) => t;`

Now when this function is called with a tuple of elements, it infers the entire tuple of elements.

For example, if we have `name: "apple"` and `name: "banana"`, it

## Transcript

0:00 The solution here ends up being pretty simple. What we can do is we can say asConst is const T here. What const T does is basically anything you pass into this will get inferred to its most literal value.

0:17 You end up getting this big readonly array here of name, "apple," price 1, name, "banana," price 2, which is super useful. Because it's read-only, too, it means that you can't even push to it, so push is not even available on it.

0:32 We can go fruits.name = blah, blah, blah, blah, blah, and it won't let us do it because it's a readonly property. This is really nice, and it basically acts as if the user had passed in as const here. You can pass in as const, but it actually won't do anything because it's triggered to understand that this is being passed in.

0:50 One thing that doesn't really work here is that you can have this outside, so you can have const config is this. Then, if you pass in config here, that's actually not going to work, if you notice, because it's already inferred its type up here. It's inferred it as an array, so we can still push to it. We can still say config.push, whatever.

1:13 You need to make sure that when you're doing this that you specify to your users, "OK, make sure you pass this in like this," but it's so useful to have this. My God.

1:22 We're going to cover a couple of other things about const annotations. If you need to support older versions than 5., then it's worth investigating the F.Narrow function from ts-toolbelt. You can actually remove this const T there and wrap the thing that you want to narrow in F.Narrow.

1:43 What this does, it doesn't quite do the same thing. We can see that asConst here, it infers it as its tuple type, which is super-duper useful, but it doesn't wrap everything in read-only. That's something to bear in mind.

1:56 I would always recommend, going forward, especially as this course goes on into the future, using const T is a pretty cool way to get around this problem.