3 ms·
Wow. The const assertion is huge. My codebases are littered with things that I, the developer, know are constant but TypeScript does not and it often takes extr
by ng12 8y ago
Wow. The const assertion is huge. My codebases are littered with things that I, the developer, know are constant but TypeScript does not and it often takes extra work to get type safety because of it. Can't wait to start using it.
- coldtea 8y agoNow following their examples clearly. Why not just make that "let x" a "const x" which JS already allows?
- kentor 8y ago"const a = {}" disallows reassignment to "a" but still allows you to mutate the object e.g. "a.b = 1". The const context does not allow you to mutate the object.
- coldtea 8y agoOK, the example with the "hello" literal string they have is quite bad then.
- karanlyons 8y ago`as const` is useful there as well, as TypeScript’s type inference only narrows as far as the type and not the literal value. `let z = {text: "hello"}` has the shape `{text: string}`, with `as const` it has the shape `{text: "hello"}`.
- coldtea 8y agoYeah, but shouldn't it use: const z = 'hello' and then get the shape {text: 'hello'} automatically? Why use "let" along with "as const" instead of mere "const x = 'hello'" for that?
- karanlyons 8y agoBecause `const` is a js level keyword that has different semantics: it applies only to the reference binding being immutable, not the value as being so. `const a = "hello"` does have the shape `"hello"` as you’d expect, since strings are immutable in js and the `const` keyword makes the binding immutable as well. But objects are mutable, so TS can’t be a superset of javascript and change the semantics of that behavior. Hence `as const`. This is different to the widening of value types within objects, which is a tradeoff made towards unsoundness with the belief that it would otherwise make interoperability with existing js too difficult, for which `as const` now serves as a way to explicitly opt into sounder behavior.
- alangpierce 8y agoFrankly it's a bit of a nuanced improvement, but I've seen it come up enough times that it's nice to have a real solution. The big value in `as const` is that `'ON' as const` has type `'ON'`, while `'ON'` has type `string`. If you have a function with a parameter of type `'OFF' | 'ON'` (a union type of two literal types), then it won't accept `string`, so you can end up in situations where the string `'ON'` won't fit because it was inferred as `string` in an intermediate step. Here's a concrete example. The `printSwitch` call fails because `state: 'OFF'` is inferred as having a `string` value. In TS 3.4, you could write `'OFF' as const` and it would work. https://www.typescriptlang.org/play/index.html#src=interface%20Switch%20%7B%0A%20%20%20%20state%3A%20'OFF'%20%7C%20'ON'%2C%0A%7D%0A%0Afunction%20printSwitch(s%3A%20Switch)%20%7B%0A%20%20%20%20console.log(s.state)%3B%0A%7D%0A%0Aconst%20s%20%3D%20%7B%0A%20%20%20%20state%3A%20'OFF'%2C%0A%7D%0A%0AprintSwitch(s)%3B%0A https://www.typescriptlang.org/play/index.html#src=interface... TS is already pretty good about this, e.g. if you write `const s: Switch = {`, then it'll have enough context clues to know that `'OFF'` should have type `'OFF'`, but the new `as const` syntax is a way to explicitly say that the type shouldn't be expanded to `string`.