Hacker Read top | best | new | newcomments | leaders | about | bookmarklet login

1. Its unclear how you can declare new generic types using @type

Here is an example type of a map function in TypeScript:

declare var map: <T, U>(f: (t:T) => U, t:T[]) => U[]

I cannot figure out the equivalent @type annotation in Closure using these docs: https://developers.google.com/closure/compiler/docs/js-for-c...



sort by: page size:

generics in typescript

seriously, generics in typescript is godsent.

it's great to be able to code in javascript while having a very supportive vscode intellisense


> TypeScript got typings right.

I have not used TypeScript, but looking at it's documentation the syntax for type annotations look identical. Would you be willing to expand on why you think its approach is better / how it's different?


What I'm after for typed annotations is integration with the closure compiler to give me static checking, so in large codebases I get that type safety, even in javascript.

Thanks anyways though


Never mind, they updated the post. As of my post the first few examples had some type annotations in the form `methodName(varName: type, ...)`, which I assumed was TS. All the examples are plain ES6 now.

Generics are supported via `@template` https://www.typescriptlang.org/docs/handbook/type-checking-j...

types can be imported either explicitly via `require()` or via the `@type {import("foo").Bar}`

There are definitely some limitations and caveats, like `Object` being aliased to `any` (I think this is being changed in a new version), but it's still way better than untyped JS, and having typescript integration is nice since our devs are already using typescript in other places.

Can even using things like https://github.com/typescript-eslint/typescript-eslint

Flow is both more advanced and faster than Typescript, but the community isn't as large, so Typescript continues to gain marketshare


Typescript has static type annotations. All those things are already easy in that context.

An early preview of typescript 0.9 adds support for generics to the language.

In case anyone missed it, example 2 is allowed in typescript.

index.d.ts:

    type FooArgs = {x: string}
    type FooResult = {y: string}
    type Foo = (_: FooArgs) => FooResult
index.js:

    /// <reference path="index.d.ts"/>
    /** @type {Foo} */
    export const foo = ({x}) => ({y: x})
Works as well

> Very rarely we find a case that we can't cover with JSDoc annotations, and most of the time it means the code could be refactored to be simpler.

Can with JSDoc define types? And can you define generic types? To me that is the real power of TypeScript, being able to type every object you use.


At this point, TypeScript should just let us define types using plain imperative TS code that will execute during static analysis. Might as well.

type MyType<T> = someFunc(T)

Of course these functions might be typed too…


I like TypeScript's syntax, but I think the way function types are declared is ugly.

If you have a function from A to B, you have to declare its type as

    type MyFunction = (arg1: A) => B
instead of

    type MyFunction = A => B
Here's that syntax applied to the example from GP:

    function call<TS extends any[], R>(fn: (...args: TS) => R, ...args: TS): R { return fn(...args); }
vs.

    function call<TS extends any[], R>(fn: ...TS => R, ...args: TS): R { return fn(...args); }

It's not external to TS. You write your types by passing object literals to the functions that generate the validators; TypeScript then infers shockingly precise types, which can be extracted using TypeScript's type manipulation utilities.

It does support generics [0].

[0] https://github.com/gcanti/io-ts/blob/master/index.md#generic...


The website seems like it needs an explanation of what this is for and when you’d want to use it; right now it leaves quite a lot to the imagination. (Also, the GitHub link in the corner (a) requires JavaScript for some reason instead of just being a normal link, and (b) goes to an empty repo so it doesn’t seem to be possible to use this thing.)

A big part of my confusion, I think, is that I’m not sure why you’d want to write code without type annotations. I can see a use for autogenerating them from code that doesn’t have any, but the first example on the page infers the return type of hello() as “t547061|string” which is rather more opaque than I’d prefer from a diagnostic. A big part of why I use TypeScript is because of the type annotations: both so future readers can understand my intent, and also to give the type checker hints about what I was thinking so it can point to exactly where I went wrong instead of going “this over here doesn’t work with that thing over there, I dunno, there’s probably something in the middle that’s not right.” So I’m curious what your thoughts are on why you dislike annotations and how to make type errors clear without leaning on them for support.


Type variables are sometimes called generics and a part of the type language, so JavaScript doesn’t have them. Typescript, but also Rust, Haskell, Java, the ML-family have them.

Type variables abstract over types and are analogous to function parameters at the values level. Think the ‘T’ in ‘List<T>’.


1) TypeScript has local type inference, meaning that `let x = returnsComplicatedThing();` will work, where in Java it would be `Complicated<Generic<Type>> x = returnsComplicatedThing();`. (At least up until the last few years)

2) TypeScript has type aliases, meaning you can write `type MyTable = List<Map<string, number | string | Foo>>` and not have to repeat yourself everywhere.

3) TypeScript has anonymous unions and tuples, so instead of writing `Triple<Integer, String, Foo>` you can just write `[number, string, Foo]`, and likewise instead of `OneOf<Integer, String, Foo>` you can write `number | string | Foo`. These are also built in and very ergonomic, so you don't have to write a OneOf4 class whenever you want to have one of 4 things, and you don't have to write helper methods to convert between different sized OneOfs.


> One can explicitly specify the type arguments of a generic function invocation or generic class instantiation in TypeScript.

  // TypeScript
  add<number>(4, 5)
  new Point<bigint>(4n, 5n)
> The above syntax is already valid JavaScript that users may rely on, so we cannot use this syntax as-is. We expect some form of new syntax that could be used to resolve this ambiguity. No specific solution is proposed at this point of time, but one example option is to use a syntactic prefix such as :

  // Types Annotations - example syntax solution
  add::<number>(4, 5)
  new Point::<bigint>(4n, 5n)
> These type arguments (::<type>) would be ignored by the JavaScript runtime. It would be reasonable for this non-ambiguous syntax to be adopted in TypeScript as well.

----

Hmm I didn't know this, so I tried it myself in Chrome's console... sure enough it works...

  new DOMPoint<Number>(4,5)
  
Given that the above works in the browser, what exactly is it doing? I've never seen angle brackets used that way in vanilla JS code

> dynamically creating types

Could you explain what you mean by this? I'm not clear on what typescript behavior this describes.


TypeScript has support for union types and generics because they aren't interchangeable. The purpose of generics is to avoid having to duplicate code or list every possible type as an input.
next

Legal | privacy