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, 1/31/2020 #36623

Closed
DanielRosenwasser opened this issue Feb 5, 2020 · 6 comments
Closed

Design Meeting Notes, 1/31/2020 #36623

DanielRosenwasser opened this issue Feb 5, 2020 · 6 comments
Labels
Design Notes Notes from our design meetings

Comments

@DanielRosenwasser
Copy link
Member

Should an Optional Chain Always Add undefined to the Type?

#36163 (comment)

const arr = [1, 2, 3, 4, 5]
const j = Math.random() * 1000 % 1;

const k = arr[j]?.toFixed();
  • If index signatures included undefined, you'd get undefined.

    • But this can go beyond that case.
  • Defensive code in general.

  • But we have plenty of places where we don't make || conservative.

    // Inferred to `number[]` because we
    // don't assume it *could* be null/undefined
    function foo(x: number[]) {
        return x || "hello"
    }
  • Okay, but are you going to trust that the user wrote ?. for a reason, or assume we have a perfect type system?

  • Seems like the indexing case is hard to explain to users

    • Okay, but maybe we could fix the indexing case?
      • Really a separate issue
  • Are people encountering this?

    • It's a new feature, and the longer we wait, the more we may hear about this.
  • Why would you write ?. on a defined type unless you planned to immediately handle them?

    • The indexing case?
    • Then let's solve the indexing case.
  • Should we also change || and &&?

    • Maybe!
    • What!? This behavior is so old, who exactly are you helping by changing that?
    • Pretty sure we need code like this to work because of how narrowing within arrays works today.
  • Discussion inconclusive

Augmenting Keys

#12754

  • Some demand to do two things:

    • Slicing/dicing strings to convert from/to camelCase, kebab-case, etc.
    • Filtering out types
    • And maybe just concatenating literals
  • Would be nice to write

    type Foo<T> = {
        [K in keyof T as StringConcat<"get-", K>]: T[K]
    };
    • Could you do something like the following?

      type Foo<T> = {
          [K in StringConcat<"get-", keyof T>]: T[K]
      };
  • Created a prototype that wires up a bunch of type aliases that have special behavior:

    type StringToUpper<K> = ...; // StringToUpper<"Foo"> -> "FOO"
    type StringToLower<K> = ...; // StringToLower<"Foo"> -> "foo"
    
    // StringSlice<"hello", 1> -> "ello"
    type StringSlice<K, Start extends number, End extends number> = ...;
    
    // StringConcat<"foo", "bar"> -> "foobar"
    type StringConcat<K1, K2> = ...;
    
    // StringMatch<"foo" | "bar" | "baz", "a"> -> "bar" | "baz"
    type StringMatch<K, Pattern extends string> = ...;
  • Won't these cause a lot of exponential explosions in the type system?

    • Sure, but we already have those.
      • Yes, But we're already trying to grapple with them.
  • Can we not use type aliases for everything here?

    • Not clear that it's better.
    • Strange that there's a magical name that has behavior instead of something core to the language.
      • But creating more operators/keywords would be a lot of new work in the parser.
  • Many of these aren't useful on generics - what if we just let people write actual code to do this?

    • Now you have to have a API on our type system.
  • Do we think this is something we want to solve?

    • Need to see the use-cases - what are people doing today?
      • Code generators? Index signatures?
    • Can't necessarily say "yes", but probably not near-term. We should be focusing on speed.
@DanielRosenwasser DanielRosenwasser added the Design Notes Notes from our design meetings label Feb 5, 2020
@threehams
Copy link

threehams commented Feb 5, 2020

Why would you write ?. on a defined type unless you planned to immediately handle them?

People new to TS often carry the need to write defensive code everywhere even if it's unnecessary. If TS implicitly added | undefined here, it would suddenly make these legitimate and make it necessary to add even more defensive code to handle the new undefined values that aren't really there at runtime.

This also seems like it would break the no-unnecessary-condition lint rule, which is really useful for changing this behavior over time.

@treybrisbane
Copy link

treybrisbane commented Feb 5, 2020

Misc. thoughts from a random user:

  • For the string concatenation case, is there a reason we couldn't just use the + operator?
    • This would mean we'd have syntactic parity between value-level concatenation and type-level concatenation
  • There's already precedent in Flow for built-in "type aliases" (e.g. $Call, $Exact, etc), so it wouldn't be too crazy IMO if TypeScript were to introduce a few
    • In fact, for better or worse, doing so would allow you guys to special-case more complex typing solutions without adding new syntax (e.g. $Awaited, $Coroutine, etc)

@DanielRosenwasser
Copy link
Member Author

We don't like the type aliases (especially the leading $), but yeah, it's the easiest way to make this "scale".

@marcesengel
Copy link

Hey @DanielRosenwasser ,

are there plans to implement the string utility types? Are you seeking contributors for those? I'd like to help, as I'm very much interested in this feature. Although I have no experience working with the TS code base at all, I'd like to invest my time. Maybe it could help me fix one bug or another in the future 😄

@DanielRosenwasser
Copy link
Member Author

No plans right now - we had a mock-up demonstrated at the design meeting, but the concern was more about complexity and speed.

@Kingwl
Copy link
Contributor

Kingwl commented Aug 19, 2020

#40124

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

6 participants