Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Design Meeting Notes, 8/16/2024 #59658

Open
DanielRosenwasser opened this issue Aug 16, 2024 · 3 comments
Open

Design Meeting Notes, 8/16/2024 #59658

DanielRosenwasser opened this issue Aug 16, 2024 · 3 comments
Labels
Design Notes Notes from our design meetings

Comments

@DanielRosenwasser
Copy link
Member

API for exposing inferred type arguments of calls

#59637

  • Is the proposed API correct? A signature is the target of the call, but is independent and the specific type arguments correspond to the signature itself.
  • Is Signature -> Type[] right? Or do you need something else? You have type arguments of signatures, but there are other type parameters in question.
  • What is it?
  • Whatever the language service does. Go to definition can be used for this.
    • Go to definition isn't a stable API for this.
  • If you have a way to get the signature as it is, you can get the type arguments.
  • Can basically use getResolvedSignature, grab the type arguments, followed by instantiateTypes with the original signature's mapper? As suggested in the isssue.
  • Yes, that sounds like the suggestion for the API.

Flag for Banning TypeScript-Specific Runtime Constructs

  • Opt-In Language Features to prevent Embrace and Extend -- Compiler options on tsc.js #2261
  • Tsconfig option to disallow features requiring transformations which are not supported by Node.js' --strip-types #59601
  • Long-standing question: how can we ban constructs that have no runtime impact (or are not trivially erasable)?
  • Possibly more impetus for this now that Node has --experimental-strip-types which replaces type constructs with whitespace.
  • What would it be called?
    • --noTranspiledFeatures
      • We transpile ESXXXX features.
    • --typeSyntaxOnly
    • --disallowRuntimeSyntax
    • --noLegacySyntax
    • --noRegerts
  • Does this flag imply --verbatimModuleSyntax and --isolatedModules?
    • The use-cases overlap a lot. We don't know why you would turn this flag on without those.
  • People seem to like typeSyntaxOnly the best.
  • This sort of thing is always weird because implementers are free to add new TS-specific constructs.
    • Well this is also about staying "pure" with ECMAScript.
  • Which are clearly not okay?
    • class C { constructor(public prop: number) {} }
    • enum of any form
    • namespace of any form
  • Are the following allowed?
    • import foo = require("foo");
    • import foo = bar.baz;
    • export =
  • Some of these can't just get erased to whitespace!
  • This is all wacky because the only reason we're revisiting this is --experimental-strip-types, which seems motivated because Node's sourcemap support is slow.
    • This is also speculative for a feature that hasn't shipped in stable.
    • Not fully true, there is also future-proofing against syntax conflicts in ECMAScript as a concern.
  • Lots of this could just be a lint rule which enforces ideological purity.
  • Some mixed feelings on whether this is a good thing to do, but there is a feel that this is not what we would do today.
  • Presumably this would be only in .ts, not .d.ts
  • Feels bad that we'd disallow enums, what is the substitute there?
    • Enums being nominal, having individual type members, etc. are all nice.
    • const foo = {...} as enum.
      • Wouldn't be a full substitute.

        const x = {
          a: 1,
          b: a, // can't do this
        } as enum;
  • What about import foo = require(...)?
    • Could support const foo = require(...) in some way, but would need a flag since a lot of code assumes this is any.
    • Is this really necessary? The hope is ESM/CJS interop will save us all.
    • A flag to add this flag? Just turn off this flag if you really need that or write const m = require("m") as typeof import("m").
@DanielRosenwasser DanielRosenwasser added the Design Notes Notes from our design meetings label Aug 16, 2024
@Andarist
Copy link
Contributor

Andarist commented Aug 16, 2024

My vote goes for --noRegerts

@acutmore
Copy link
Contributor

acutmore commented Aug 18, 2024

as enum 😍.

FWIW import foo = require("foo"); can be position preserving transformed because import is longer than const.

export = is the one that is shorter than module.exports =.
Also "use strict" gets added to the top, which could maybe be an error if omitted in the source? (Maybe nice to remind people that this is needed for CJS).

@ritschwumm
Copy link

how about replacing namespace - is there any good way to write this without requiring a second module or a separate type for an object containing the Foo functions?

// foo.ts

export type Foo = { ... }

export namespace Foo {
    export const doSomething = (foo:Foo):Foo => { ... }
}

// bar.ts

import { Foo } from "./foo";

const a:Foo = ...;
Foo.doSomething(a);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Design Notes Notes from our design meetings
Projects
None yet
Development

No branches or pull requests

4 participants