Rendered at 08:38:05 GMT+0000 (Coordinated Universal Time) with Cloudflare Workers.
alembic_fumes 3 days ago [-]
> strict is now true by default
I would still have a full head of hair if this had been the case since the beginning. Nonetheless I am glad that we got here in the end.
Analemma_ 3 days ago [-]
TypeScript never would’ve taken off if it had been strict from the beginning, it would’ve been just another forgotten gravestone next to Dart and CoffeeScript. I’m not saying those are bad languages, they’re not, but anything other than a very slow and gradual opt-in transition was just a non-starter. It was painful, but TypeScript played the long game.
paulddraper 3 days ago [-]
Many of the strict checks did not even exist when TS was first created.
romellem 16 hours ago [-]
Some of these missing checks were why Flow was an attractive choice when weighing [Flow vs Typescript][1].
For example, it wasn't until Typescript 2.0 that we got null checks!
function getLength(s: string): number {
return s.length; // Runtime crash if s is null/undefined
}
getLength(null); // TypeScript <2.0 would not error here
I came to point that out too. What an awesome development. I think this will have a meaningful impact on the general quality of TS projects over the coming years.
3 days ago [-]
chrysoprace 3 days ago [-]
If it had been, maybe I wouldn't have had to spend years getting buy in for turning on that setting in my team's codebase.
369548684892826 3 days ago [-]
Just use deno
paulddraper 3 days ago [-]
Exactly when do you think demo started.
mdtrooper 3 days ago [-]
What has always bothered me about TypeScript are union types. If you have a function that receives a parameter such as ‘Dog | Cat’, you cannot separate it. For example:
type Dog = { bark: () => void }
type Cat = { meow: () => void }
function speak(animal: Dog | Cat) {
if (‘bark’ in animal) {
animal.bark();
} else {
animal.meow();
}
}
Okay, okay, I know you can filter using ‘in’ to see if it has methods, but in real life, in a company where you have a colleague (who is a golden boy) who writes over-engineered code with hundreds of interfaces of interfaces, you don’t want to spend time searching through the files to find every element that is in the union type.
Whereas in Rust it does:
struct Dog {
name: String,
}
struct Cat {
name: String,
}
enum Animal {
Dog(Dog),
Cat(Cat),
}
fn process_animal(animal: Animal) {
match animal {
Animal::Dog(dog) => {
println!(‘It is a dog named {}’, dog.name);
}
Animal::Cat(cat) => {
println!(‘It is a cat named {}’, cat.name);
}
}
}
I think TypeScript should add a couple of lines of code to the generated JavaScript to do something like:
type Dog = { bark: () => void }
type Cat = { meow: () => void }
function speak(animal: Dog | Cat) {
if (animal is Dog) {
animal.bark();
} else {
animal.meow();
}
}
tshaddox 3 days ago [-]
The idiomatic way to do this in TypeScript is with discriminated unions. You’re basically just giving the type system an extra property that makes it trivial to infer a type guard (while also making the runtime check in the compiled JavaScript foolproof).
culi 3 days ago [-]
This does act exactly as a discriminated union. The code works exactly as written.
paulddraper 3 days ago [-]
You're looking for a discriminated union [1], which idiomatically:
type Dog = { bark(): void; type: 'dog' }
type Cat = { meow(): void; type: 'cat' }
function speak(animal: Dog | Cat) {
if (animal.type === 'dog') {
animal.bark()
} else {
animal.meow()
}
}
Generally speaking, TypeScript does not add runtime features.
TypeScript checks your use of JavaScript runtime features.
Typeguard is what you are looking for: function isDog(animal: Dog | Cat): animal is Dog { return "bark" in Dog }
Then: isDog(animal) ? animal.bark() : animal.meow()
You get full type narrowing inside conditionals using typeguards.
culi 3 days ago [-]
You don't even need that. The code exactly as presented acts as a discriminator. TypeScript is smart enough to handle that logic in the if block and know whether animal has been validated as Dog vs Cat. GP is complaining about a feature that already exists in TypeScript
JoeyJoJoJr 3 days ago [-]
I’m not at my computer so I can’t remember the exact behavior of this situation, but was OP more so referring to autocomplete abilities of typescript? I think they were saying, you first must know if the object barks or meows, you must first type that in in order to get the benefit of type checking and subsequent autocomplete conditional body, which is annoying when you are dealing with complicated types. It requires you to do some hunting in to the types, rather than using a piece of code more like an interface.
littlecranky67 3 days ago [-]
It depends how you construct Dog and Cat. With Javascripts dynamic prototype chain, you could never know for sure.
You're both misunderstanding parent's point as well as the original point. Nobody ever claimed your link wouldn't compile.
culi 3 days ago [-]
I see what you mean, thanks
Well imo GP is fundamentally misunderstanding TypeScript. It's explicitly a structural language not a nominal one. It goes against the entire design philosophy of TS
reitzensteinm 3 days ago [-]
It would have been a super reasonable reply to talk about the history of TypeScript, why fundamentally its types exist to retroactively describe complicated datastructures encountered in real world JavaScript. And why when TypeScript overstepped that by creating enums, which require code generation and not mere type erasure to compile, it was decided to be a mistake that they won't repeat.
But instead your rebuttal was pointing out that TypeScript can compile OP's example code, which OP presented as valid TypeScript that they disliked. I'm not defending their position, I'm just saying that it didn't appear you had even properly read their comment.
3 days ago [-]
spankalee 3 days ago [-]
You're talking about adding a runtime feature. TypeScript doesn't do that anymore. It can't control what properties are on objects or add new ones - you do that yourself in the standard JavaScript portion of the language. TypeScript only lets you describe what's there.
As a sibling said, discriminated unions are they way to go here. You can also add custom type guard functions if you can't control the objects but you want to centralize the detection of the types, but it's better to let TypeScript do it itself so that you don't mess something up with a cast.
dimava 3 days ago [-]
And then you have a
const CatDog = { bark(){}, meow(){} }
and
const TreeCat = { bark: "oak", meow(){} }
and your code stops working
To make types discriminatable you need either
type A = { bark: fn, meow?: never } | { bark?: never, meow: fn }
type B = { species: "dog", bark: fn } | { species: "cat", meow: fn }
or use instanceof with a class
What always bothers me with enums, sealed-types, etc is that I can't compose a new ad-hoc set based on elements of someone else's enum. You can make one using the other but not the other way around, TypeScript's is more general.
castral 3 days ago [-]
You can literally do what your generated example does using a type guard. You can also use method overloaded signatures if you dont want to expose your API consumers to union types.
For anyone who isn't aware, TypeScript does not use semantic versioning.
Though TypeScript 7.0 will be significant in that it will use the new Go compiler
joshkel 3 days ago [-]
Appreciate the reminder (the lack of SemVer has thrown me in the past). In this case, 6.0 is a bigger change than normal:
> TypeScript 6.0 arrives as a significant transition release, designed to prepare developers for TypeScript 7.0, the upcoming native port of the TypeScript compiler. While TypeScript 6.0 maintains full compatibility with your existing TypeScript knowledge and continues to be API compatible with TypeScript 5.9, this release introduces a number of breaking changes and deprecations that reflect the evolving JavaScript ecosystem and set the stage for TypeScript 7.0.
tshaddox 3 days ago [-]
Semantic versioning seems slightly weird to even apply to something like TypeScript. You could have patch releases that fix actual compiler crashes, sure, but what is a minor release?
Surely any new feature that causes code to fail to type check when it previously would pass (or vice versa) would have to be considered a breaking change.
A similar thing applies to code formatting tools like Prettier, or any linter.
spankalee 3 days ago [-]
Semantic versions would at least be playing nice with how npm manages version ranges. If every release of TypeScript is breaking, then you should use major versions so that `npm update` doesn't break your project.
Yes, typescript would be at version 60 now. No, that's not a problem at all. Numbers are free.
ukuina 3 days ago [-]
> Numbers are free.
Someone please tell the LLM naming committee.
pscanf 3 days ago [-]
As a user, I'm of course very excited about v7. As a developer of an app that _integrates_ TypeScript, however, I feel a bit uneasy seeing the API feature still marked as "not ready" on the roadmap.
On the other hand, I can understand leaving it as the last thing to do, after the foundation has set. Also, the TypeScript team has really done an amazing job all these years with backward compatibility, so that is extremely reassuring.
Maybe my uneasiness is just impatience to get to use the sped-up version in my app as well! :)
tanepiper 3 days ago [-]
FWIW I tried it with the VSCode preview in two monorepos we have - one frontend and one backend GraphQL servers with complex types - absolutely no issues (except one breaking change in tsconfig with baseUrl being removed) and fast compile times.
silverstream 3 days ago [-]
Same experience here with a pnpm workspace monorepo. The baseUrl removal was the only real friction — we were using it as a path alias root, had to move
everything to subpath imports.
The moduleResolution: node deprecation is the one I'd flag for anyone not paying attention yet. Switching to nodenext forced us to add .js extensions to all
relative imports, which was a bigger migration than expected.
Compilation speed improvement is real though. Noticeably faster on incremental builds.
spankalee 3 days ago [-]
As a developer that integrates typescript into client-side web pages and writes lots of custom plugins, I'm extremely nervous about the port to Go.
I think the last estimate I saw was the the Go port compiled to WASM was going to be about triple the size of the minified JS bundle.
pjmlp 3 days ago [-]
I would rather have seen C# Native AOT for the Typescript 7, alongside Blazor for the playground, but it is what is.
Now when .NET team complains about adoption I get to point out Typescript 7's contribution repo.
And yes I know the reasons, my nick is on the discussions, please also watch the BUILD session where they acknowledge having to rewrite the whole datastructures due to Go's weaker type system.
lenkite 3 days ago [-]
Yeah, its strange that Microsoft is not dogfooding its own stuff. Even as an "enterprise" Go developer myself, I would have preferred that Typescript was written in C# - it keeps language ecosystems diverse. And ensures that C# continues to improve.
CuriousRose 3 days ago [-]
I am hoping that eventually there will be some agnosticism with the language server. Currently they all seem to rely on Node which in my opinion is rapidly being outclassed by Bun in terms of resource usage. It would be great to eventually be able to pick what runtime they use in VS Code/Cursor to reduce energy drain on my laptop when working on the go.
djrenren 3 days ago [-]
The typescript language server (along with the rest of the compiler) is being rewritten in go for Typescript 7. This work has been going on in parallel with the work on 6.0. The go port has most features of 6.0 already and you can follow its progress and read more about it here:
Sure, but instead of waiting another year for this to be launched - with a beta version precaution and inevitable bugs - why not remove the limited hard-coded Node paths and references now and ship something 80:20?
djrenren 3 days ago [-]
If it’s a simple change, they might accept a PR. If it isn’t, well that’s your answer. Not worth allocating engineers for it.
It would have been an affront to have a 6.0 that shipped without the means to work for so so many javascript frameworks/libraries. AlCalzone utterly saving the day.
I also am so so so thankful that maybe perhaps after what felt like a never ending dolldrums, we may finally be getting decorator support in some browsers. What a colossal relief it will be to see the progress of the language become manifest.
ukuina 3 days ago [-]
> Disclaimer: This is an entire day worth of Claude Opus tokens. I don't claim I understand how it works, but I did my best to direct Claude to minimize the baseline diffs, of which it removed quite a few.
TypeScript allows entirely LLM-coded PRs?
tmaly 3 days ago [-]
I had no idea they were using Go to write a compiler.
I would still have a full head of hair if this had been the case since the beginning. Nonetheless I am glad that we got here in the end.
For example, it wasn't until Typescript 2.0 that we got null checks!
- https://www.typescriptlang.org/docs/handbook/release-notes/t...
[1]: https://djcordhose.github.io/flow-vs-typescript/2016_hhjs.ht...type Dog = { bark: () => void }
type Cat = { meow: () => void }
function speak(animal: Dog | Cat) {
}Okay, okay, I know you can filter using ‘in’ to see if it has methods, but in real life, in a company where you have a colleague (who is a golden boy) who writes over-engineered code with hundreds of interfaces of interfaces, you don’t want to spend time searching through the files to find every element that is in the union type.
Whereas in Rust it does:
struct Dog { name: String, }
struct Cat { name: String, }
enum Animal {
}fn process_animal(animal: Animal) {
}I think TypeScript should add a couple of lines of code to the generated JavaScript to do something like:
type Dog = { bark: () => void }
type Cat = { meow: () => void }
function speak(animal: Dog | Cat) {
TypeScript checks your use of JavaScript runtime features.
[1] https://www.convex.dev/typescript/advanced/type-operators-ma...
https://www.typescriptlang.org/play/?#code/C4TwDgpgBAIg9gcyg...
I thought the answer was 'instanceof'?
https://www.typescriptlang.org/docs/handbook/2/narrowing.htm...
You can't do `instanceof Dog`. `instanceof` is a JavaScript feature
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...
Then: isDog(animal) ? animal.bark() : animal.meow() You get full type narrowing inside conditionals using typeguards.
https://www.typescriptlang.org/play/?#code/C4TwDgpgBAIg9gcyg...
const imposter: Mutt = { bark: () => console.log("woof"), meow: () => console.log("meow"), }
You're both misunderstanding parent's point as well as the original point. Nobody ever claimed your link wouldn't compile.
Well imo GP is fundamentally misunderstanding TypeScript. It's explicitly a structural language not a nominal one. It goes against the entire design philosophy of TS
But instead your rebuttal was pointing out that TypeScript can compile OP's example code, which OP presented as valid TypeScript that they disliked. I'm not defending their position, I'm just saying that it didn't appear you had even properly read their comment.
As a sibling said, discriminated unions are they way to go here. You can also add custom type guard functions if you can't control the objects but you want to centralize the detection of the types, but it's better to let TypeScript do it itself so that you don't mess something up with a cast.
To make types discriminatable you need either
Though TypeScript 7.0 will be significant in that it will use the new Go compiler
> TypeScript 6.0 arrives as a significant transition release, designed to prepare developers for TypeScript 7.0, the upcoming native port of the TypeScript compiler. While TypeScript 6.0 maintains full compatibility with your existing TypeScript knowledge and continues to be API compatible with TypeScript 5.9, this release introduces a number of breaking changes and deprecations that reflect the evolving JavaScript ecosystem and set the stage for TypeScript 7.0.
Surely any new feature that causes code to fail to type check when it previously would pass (or vice versa) would have to be considered a breaking change.
A similar thing applies to code formatting tools like Prettier, or any linter.
Yes, typescript would be at version 60 now. No, that's not a problem at all. Numbers are free.
Someone please tell the LLM naming committee.
On the other hand, I can understand leaving it as the last thing to do, after the foundation has set. Also, the TypeScript team has really done an amazing job all these years with backward compatibility, so that is extremely reassuring.
Maybe my uneasiness is just impatience to get to use the sped-up version in my app as well! :)
I think the last estimate I saw was the the Go port compiled to WASM was going to be about triple the size of the minified JS bundle.
Now when .NET team complains about adoption I get to point out Typescript 7's contribution repo.
And yes I know the reasons, my nick is on the discussions, please also watch the BUILD session where they acknowledge having to rewrite the whole datastructures due to Go's weaker type system.
https://github.com/microsoft/typescript-go
It would have been an affront to have a 6.0 that shipped without the means to work for so so many javascript frameworks/libraries. AlCalzone utterly saving the day.
I also am so so so thankful that maybe perhaps after what felt like a never ending dolldrums, we may finally be getting decorator support in some browsers. What a colossal relief it will be to see the progress of the language become manifest.
TypeScript allows entirely LLM-coded PRs?