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/31/2018 #26954

Closed
DanielRosenwasser opened this issue Sep 7, 2018 · 2 comments
Closed

Design Meeting Notes, 8/31/2018 #26954

DanielRosenwasser opened this issue Sep 7, 2018 · 2 comments
Labels
Design Notes Notes from our design meetings

Comments

@DanielRosenwasser
Copy link
Member

DanielRosenwasser commented Sep 7, 2018

Narrowed read-only properties in functions

#9511

  • We usually disregard narrowing for values captured in functions.
    • Unless they're const.
  • We don't narrow in functions for properties.
    • Someone
  • However, as mentioned readonly doesn't disallow aliasing of a mutable value.
    • const has different semantics
  • You can think of readonly as a read-only view into some value.
    • Aliasing means you can't guarantee other mutations

      let y: { a: string | undefined } = { a: 's' }
      const x: { readonly a: string | undefined } = y;
      if (typeof x.a !== 'undefined') {
          y.a = undefined;
          () => x.a.length;
      }
  • If we look at some examples in Trade-offs in Control Flow Analysis #9998, it seems somewhat arguable.
  • Given the fact the you only have write-ability restrictions on your reference of a property,
  • Conclusion: let's close it

Changing implicit constraints from {} to unknown

#26796

  • We have assumptions that all type parameters (e.g. T) are assignable to {}, even though an instantiation may be null or undefined.

  • Really, we should say that the default constraint for all generics are unknown.

  • This would definitely break stuff.

    • The question is not whether this will break stuff, but
      • how much will it break?
      • are the breaks good?
  • We didn't want to "rock the boat" when we shipped strictNullChecks by changing the constraints.

    • Didn't have unknown at the time.
    • The type would be unreadable as {} | null | undefined.
  • Would want to do this in strictNullChecks?

  • What about outside of strictNullChecks?

    • Maybe we should make unknown assignable to {}.
      • Sounds like you're pushing the problem down the road if you ever switch into strictNullChecks?
        • But that's future-you's problem.
  • Should consider unknown the "toppest" type.

  • Idea: we really only want new errors in the declaration, not call sites:

    function foo<T extends unknown>(x: T, y: T) {
      // declaration
      let z: {} = x;
    }
    
    // call
    foo(null, 100);
  • Should we also be looking at all the places in the compiler that use {}?

    • Probably.
  • Conclusion: let's try changing the default constraint for type parameters to unknown (and also change them not to be assignable to {} (but only to unknown)).

    • see what breaks

Support for "typesVersions" redirects

#26568

  • We currently can't make changes to Node's .d.ts because of backwards-compatibility.
  • Ideally, we could publish one package that had all the versions in different .d.ts files.
  • Other situation: someone wants to use the latest features of TypeScript, but those features end up in their .d.ts files.
  • Proposal: typesVersions
    • A new field in package.json that maps versions ranges to path-mappings.
  • We also discussed encoding this information into file names when resolving.
    • Coming up with a resolution strategy seems a litle bit fuzzy.
  • Do you need both a types and a typesVersions field in package.json?
    • Yes! At least if you care about older versions of TypeScript (e.g. versions prior to whenever typesVersion was supported). In those cases, types should point to a file that supports the oldest version of TypeScript.
  • Does this really solve the "new types leak into my .d.ts files" issue?
    • Depends on what you want to do.
      • If your API doesn't change that much, ship stale .d.ts and maybe that's okay.
      • Otherwise you can write a tool that replaces types.
  • Is this compatible with the tagging strategy on DefinitelyTyped?
    • Currently the types-publisher tool looks for // TypeScript Version: X.Y on .d.ts file headers in DefinitelyTyped and tags them as tsX.Y.
    • We may be able to stop publishing tags.
      • ...but it might be safer to wait a version.
  • How does this interact with the layouts for different package versions in DefinitelyTyped?
    • @andy-ms is coming up with a proposal.
  • Concerns about complexity, but this is meant for power-user package authors.
@DanielRosenwasser DanielRosenwasser added the Design Notes Notes from our design meetings label Sep 7, 2018
@mattmccutchen
Copy link
Contributor

mattmccutchen commented Sep 7, 2018

Ooh, my issue made the design meeting! But it's #26796, not #26797. +1 to unknown being assignable to {} outside strictNullChecks; that's consistent with the idea that unknown = {} | null | undefined.

@yortus
Copy link
Contributor

yortus commented Sep 7, 2018

regarding changing implicit constraints from {} to unknown:

  • Should we also be looking at all the places in the compiler that use {}?
    • Probably.

Another implicit type that should be unknown is the catch clause variable, which cannot be annotated and is currently given the type-unsafe any type. Obviously changing this would also be breaking. Is it worth trying and seeing what breaks there too?

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