tc39 / proposal-pattern-matching

Pattern matching syntax for ECMAScript
https://tc39.es/proposal-pattern-matching/
MIT License
5.5k stars 89 forks source link

Why not Typescript-like syntax? #312

Closed lilnasy closed 10 months ago

lilnasy commented 10 months ago

The proposal seems heavily influenced from compiled languages. I am curious if syntax similar to typescript's was considered.

If-block on an array

if (array extends [1, 2, ...infer rest]) {
   console.log("the other elements from an array that starts with 1 and 2", rest)
}

If-block on a string

if (path extends `file://${infer filePath}`) {
    console.error(`path must not be file url, did you mean ${filePath}?`)
} else if (path extends `http://${infer insecurePath}`) {
    ...
}

Switch-block on an array

const fiveIntegers = integers(5);
switch (fiveIntegers) {
    extends [infer a]: return console.log(`found one int: ${a}`);
    extends [infer a, infer b]: return console.log(`found two ints: ${a} and ${b}`);
    default: return console.log("more than two ints");
}

Switch-block on an object

const randomItem = {
    get numOrString() { return Math.random() < .5 ? 1 : "1"; }
};

switch (randomItem) {
    extends { numOrString: infer num extends Number }:
        console.log("Only matches half the time.");
    extends { numOrString: infer str extends String }:
        console.log("Guaranteed to match the other half of the time.");
}
ljharb commented 10 months ago

Seems like that would be pretty confusing in TypeScript codebases.

Jack-Works commented 10 months ago

your example, but in the latest proposal (not merged yet) we have:

if (array is [1, 2, ...let rest]) {}

if (path is /^file:\/\/(?<let filePath>.+)$/) {
} else if (path extends /^http:\/\/(?<let insecurePath>.+)$/) {}

// with https://github.com/tc39/proposal-do-expressions
match (fiveIntegers) {
   [let a]: do { return ...; }
   [let a, let b]: do { return ...; }
   default: do { return ...; }
}

match (randomItem) {
    { numOrString: let num and Number }:
        ...;
    { numOrString: let str and String }:
        ...;
}
lilnasy commented 10 months ago

That is exactly how I imagined it. Love it!

and as the keyword seems non-obvious but I'll look at the PR to see if it makes sense.