3 ms·
Well I'd love to hear some concrete examples if you have any on hand! I was of the same opinion as you until I refactored a project of mine to use JSDoc. Since
by culi 11mo ago
Well I'd love to hear some concrete examples if you have any on hand! I was of the same opinion as you until I refactored a project of mine to use JSDoc.
Since any TypeScript type can be expressed in JSDoc, I imagine you're mostly thinking of generics. At least that was my main sticking point. JSDoc does actually have generic slots with the @template tag. Actually using them in practice is a little unintuitive but involves typing the return type. E.g. for a function it'd look like this:
/** @type {ReturnType<typeof useState<Book[]>>} */
const [books, setBooks] = useState();
- efortis 11mo agoand types can be written in .d.ts file(s), which can be used in jsdoc out of the box (no import needed)
- g947o 11mo agoYou could, but in a large codebase with multiple contributors, it easily becomes messy and confusing.
- mirekrusin 11mo agothat's not "jsdoc is typescript" anymore because you're falling back to something else - type definition files where you do have access wider typescript functionality. also not a full solution - for .d.ts types to be available globally without explicit import the .d.ts file itself cannot use any imports/exports. this means you can't reuse types from other places to construct your types. you can workaround this by explicitly importing .d.ts in jsconfig/tsconfig but you're still left with other issues. those types do actually become globally visible everywhere polluting global namespace which is bad in itself there are no guarantees about them being in sync with actual code, which violates the whole point of using type safety. they don't solve cases where you need typescript inlined functionality locally in your code or to perform assertion with satisfies operator etc.
- afavour 11mo agoReturnType is TypeScript, no? You’re using JSDoc to express but it’s a TypeScript type.
- g947o 11mo agoSupport for generics is limited in JSDoc compared to TypeScript, especially when arrow function is involved. Things that work fine in TypeScript trigger errors even though they are syntactically the same.
- culi 11mo agoBecause AirBnB's ESLint config has been burned into my brain I almost only use arrow functions. I also use generics extremely often. It's definitely a little more clunky but I haven't run into anything you can do in TypeScript that you can't do in JSDoc. JSDoc also allows you to type stuff in-line. For example I often have to type an empty array like so: const [books, setBooks] = useState(/** @type {Book[]} */([])); If you have a tangible example of a problem you've run into, I'd love to walk through it.
- g947o 11mo agoJavaScript example: https://www.typescriptlang.org/play/?filetype=js#code/PTAEAEBcGcFoGMAWBTeBrAUB4AqHHQcJJkBbABwBsBDE0AFQKPHmssoCNr1QB1AS0iIAMgHsA5uP4A7cQGE2nbpkIRy1AE7VSoAN4AzAK7T4kfqOkAKAJQAuegF9Qrdl3RMIG5JEMbp0PUcmYCxcfFUoMipaZAYPKABPcljdASExSRl5RTc0AB56AD4HYIx4C2hIUAB3QREJKVlQAF5QfRbCvQJQHvL-UUpkADpKCUsAclHM2QBCcetu3oqqr2hDSirW-RsAbkXQLx8-A+Q1jb2HPYwjEzMLUHFvAC1kDVFQGy6ensPfaVAAAwXUJ4eLqLQ6VJ1DKNbKuZROADaU1hzVq6QaWQAuvFfn4ArppIZSBxXiVCCEbqZzP8ACaiXiiDRoD4orItGrQzGyaxfb54-5s2SWR6QF5vawXIA https://www.typescriptlang.org/play/?filetype=js#code/PTAEAE... Almost equivalent typescript code: https://www.typescriptlang.org/play/?#code/C4TwDgpgBA6glsAFgGQPYHN1wHboMICGANkQEYEDGA1lALxQA8AKgHwAUFxZlVAXFGwCUdFlCbDaopgG4AULIqpsAZ2BQA7ghQYsufvCRpMOfF3LU6UAGYioAb1lQnURStREIAOiIY2Ach9jXABCP0FHZ1dVKAAnCGUAVyI1eishOWdYiGAEmOwsxOS5AF95KwTsCmA4JSh0bIAtCBjUAWEHTLicvKgABhKyiqqa-IATVBhUGJo2QN10fS0jecIScxp6TUMdE3aIpy7c-LmTNnrgJpbBEqA https://www.typescriptlang.org/play/?#code/C4TwDgpgBA6glsAFg... (I had to make it a little bit different from the JS code to make it compile) (Well, this is not exactly about arrow function I guess. I remembered that part wrong.) Note that I cannot make the type check in JS code to pass. Whatever I do, there is always a error. Meanwhile, it does not take much to TS code to work.
- culi 11mo ago
- g947o 11mo agoLast time I checked, there isn't a way to extend types (https://www.typescriptlang.org/docs/handbook/2/objects.html#extending-types https://www.typescriptlang.org/docs/handbook/2/objects.html#...) that works exactly like in TypeScript.
- auxiliarymoose 11mo agoYou can use `&` operator to combine types. Works for adding fields, making branded types, etc.
- g947o 11mo agowhich is not the same as "extends".
- spoiler 11mo agoThere's also a slight performance caveat when it comes to interfaces vs intersections (&) to keep in mind: https://github.com/microsoft/Typescript/wiki/Performance#preferring-interfaces-over-intersections https://github.com/microsoft/Typescript/wiki/Performance#pre...
- deleted 11mo ago[deleted]
- culi 11mo agoJSDoc actually has the @extends tag /** * @typedef {object} Dog @extends Animal * @property {string} childProp */ But I don't really use that feature in TypeScript. Instead I rely on `&`. This works in exactly the same way in JSDoc. Also if you're curious about the equivalent of `extends` in generic slots, here's an example I have from a different project /** * @template {Record<string, unknown>} [T=Record<string, unknown>] * @typedef {{ * children?: NewickNode<T>[]; * name?: string; * length?: number; * data?: T; * }} NewickNode */ The generic slot here, T, is "extended" by Record<string, unknown>. The equivalent in TypeScript would look like type NewickNode<T extends Record<string, unknown> = Record<string, unknown>> = { children?: NewickNode<T>[]; name?: string; length?: number; data?: T; };
- mirekrusin 11mo agoThings like type star imports, destructured imports or satisfies operator don't work in jsdoc. All non erasable constructs won't work as well of course but playing devil's advocate you could explicitly state that you're interested in erasable constructs only because ie. 1) that's what typescript should be doing from day 1 and/or 2) it seem to be the future with ie. nodejs adopting built in type erasure support.