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

Improve best type matching for elementwise elaborations #57537

Open
wants to merge 9 commits into
base: main
Choose a base branch
from

Conversation

Andarist
Copy link
Contributor

@Andarist Andarist commented Feb 25, 2024

fixes #57541

This PR improves error locations for elementwise error elaborations in a couple of situations. It often finds a better property candidate for the printed error - so the highlighted error is way closer to the actual problem, and it's easier to focus on it. At times, when finding a candidate property when previously it couldn't find any, it also reduces the error span - which is also less distracting.

@Andarist Andarist marked this pull request as ready for review February 26, 2024 07:22
@typescript-bot typescript-bot added the For Uncommitted Bug PR for untriaged, rejected, closed or missing bug label Feb 26, 2024
const idx = getIndexedAccessTypeOrUndefined(target, nameType);
if (idx) {
return idx;
}
if (target.flags & TypeFlags.Union) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

swapping the order of operations here improves some errors quite a bit in my eyes since the union discrimination happens early, for example:

const obj6: {
  prop:
    | {
        type: "foo";
        prop: string;
      }
    | {
        type: "bar";
        prop: number;
      };
} = {
  prop: {
    type: "foo",
    // current: Type 'boolean' is not assignable to type 'string | number'.
    // pr: Type 'boolean' is not assignable to type 'string'
    prop: true,
  },
};

const obj7: {
  prop:
    | {
        type: "foo";
        prop: string;
      }
    | {
        type: "bar";
        prop: number;
      };
} = {
  // current: Type '{ type: "foo"; prop: number; }' is not assignable to type '{ type: "foo"; prop: string; } | { type: "bar"; prop: number; }'.
  //  Types of property 'prop' are incompatible.
  //    Type 'number' is not assignable to type 'string'.
  prop: {
    type: "foo",
    // pr: Type 'number' is not assignable to type 'string'.
    prop: 42,
  },
};

@@ -21983,8 +21984,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
}
}
if (reportErrors) {
// Elaborate only if we can find a best matching type in the target union
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I removed this union from here because it was misleading - the containing function handles both unions and intersections. However, from what I can tell reportErrors: true is only ever passed in for unions - I can revert this if requested

// Elaborate only if we can find a best matching type in the target union
const bestMatchingType = getBestMatchingType(source, target, isRelatedTo);
// Elaborate only if we can find a best matching type in the target
const bestMatchingType = getBestMatchingType(source, target, /*matchSingleOverlappy*/ true, isRelatedTo);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Returning a single overlappy type is required here to make the non-elementwise union-based elaboration to elaborate about the "last" element in the union, see the "recovered" errors in this commit: e9d136a

@@ -50901,10 +50901,18 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
}
}

function findBestTypeForObjectLiteral(source: Type, unionTarget: UnionOrIntersectionType) {
if (getObjectFlags(source) & ObjectFlags.ObjectLiteral && someType(unionTarget, isArrayLikeType)) {
return find(unionTarget.types, t => !isArrayLikeType(t));
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The referenced bug was a somewhat funny one because optional properties always include | undefined in their types and undefinedType is always kept at the beginning of unionType.types. So in such a situation this was always returning that undefinedType - making it impossible to create a good elementwise elaboration.

!(t.flags & TypeFlags.Primitive) &&
!isArrayLikeType(t) &&
!typeHasCallOrConstructSignatures(t) &&
(everyContainedType(t, t => !t.symbol || !(t.symbol.flags & SymbolFlags.Class)) || !containsNonPublicProperties(getAugmentedPropertiesOfType(t))));
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is quite related to #56183 - although completions and contextual types are orthogonal to elementwise elaborations. I only figured out that I should filter those nominal types here because I was working on that other PR in the past

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed errors here might feel a little bit questionable. I feel like it's a good change and that it indirectly matches some other situations.

Let's take a look at this one:

function test(_: { children: [string, number] | boolean[] }) {}

const children = [{}, ""] satisfies [unknown, unknown];

test({
  // Type '[{}, string]' is not assignable to type '[string, number] | boolean[]'.
  //   Type '[{}, string]' is not assignable to type '[string, number]'.
  //     Type at position 0 in source is not compatible with type at position 0 in target.
  //       Type '{}' is not assignable to type 'string'.(2322)
  children,
});

Regardless of the order of this union we get the same error. The tuple gets priority selection here and that's exactly what happens with my changes here. Since getBestMatchingType gets called before getIndexedAccessTypeOrUndefined I now select the tuple through findMatchingTypeReferenceOrTypeAliasReference.

If you feel strongly about it I can work on special-casing tuples/arrays in this algorithm.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Those errors were improved based on overlapping type selection. Even though the discriminant property has the error (so we can't quite know which type it was supposed to be) - the other properties indicate the user's intention.

!!! error TS2322: Type '{ kind: "A"; n: { a: string; b: string; }; }' is not assignable to type 'AB'.
!!! error TS2322: Types of property 'n' are incompatible.
!!! error TS2322: Object literal may only specify known properties, and 'b' does not exist in type 'AN'.
!!! error TS2353: Object literal may only specify known properties, and 'b' does not exist in type 'AN'.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This feels like a straight improvement - this was supposed to look like this since #55152 (cc @RyanCavanaugh - maybe it would be worth rechecking if the approach used by that PR doesn't have any other holes)

@Andarist Andarist force-pushed the fix/elementwise-errors-best-type-obj-literal branch from 78fd6d9 to e295774 Compare February 26, 2024 08:39
@DanielRosenwasser
Copy link
Member

@typescript-bot perf test this

@typescript-bot
Copy link
Collaborator

typescript-bot commented Feb 26, 2024

Heya @DanielRosenwasser, I've started to run the regular perf test suite on this PR at e295774. You can monitor the build here.

Update: The results are in!

@@ -14,7 +14,7 @@ indirectDiscriminantAndExcessProperty.ts(22,5): error TS2322: Type 'string' is n
thing({
type: foo1,
~~~~
!!! error TS2322: Type 'string' is not assignable to type '"foo" | "bar"'.
!!! error TS2322: Type 'string' is not assignable to type '"foo"'.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Heh - this is kind of better if you're already familiar with string literals, but I'd argue overall worse in that it doesn't give as much of a hint that type is really the discriminant. I don't think it's a blocker though.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that this isn't related to discriminants here. This case just happens to have a discriminant target.

The reason this has changed is that previously getBestMatchIndexedAccessTypeOrUndefined would prefer the simple match done using getIndexedAccessTypeOrUndefined. Since type is a shared property in the union target that would return early and the error with the union type would be raised. Now getBestMatchingType is preferred so this new error here is the product of the best overlappy type matching.

This now matches more closely the non-elementwise error reported in the very same situation, see the playground here

@@ -20,9 +20,9 @@ index.tsx(11,6): error TS2769: No overload matches this call.
~~~
!!! error TS2769: No overload matches this call.
!!! error TS2769: Overload 2 of 2, '(props: PropsType, context: any): Foo', gave the following error.
!!! error TS2769: Type 'unknown' is not assignable to type 'string | boolean'.
!!! error TS2769: Type 'unknown' is not assignable to type 'string'.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This does seem worse overall, but it feels like JSX children should have better messages.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I touched on this here. Let me know if that makes any sense or if you think I should work more on improving this case.

Comment on lines +43 to +44
!!! error TS2322: Type 'number' is not assignable to type 'undefined'.
!!! related TS6500 objectLiteralNormalization.ts:11:19: The expected type comes from property 'b' which is declared here on type '{ a: number; b: number; } | { a: string; b?: undefined; } | { a?: undefined; b?: undefined; }'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unlike the other regressions, it really feels like we've lost too much context here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't the related info contain the same information that was reported previously in the non-elementwise error? What would be your ideal outcome here? It could be nicer if the error would focus on the selected best type and not on the containing union.

I wouldn't call this bit a regression per se - the same information is still here, it's presented differently though. And, of course, the presentation does matter - I'm not claiming that it doesn't.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FWIW: That error is confusing. It starts out saying number isn't assignable to undefined, which is true, but then goes on to claim that the "expected type" comes from b of { a: number; b: number; } | { a: string; b?: undefined; } | { a?: undefined; b?: undefined; }. Now, given that union as the target type, if the b in the source is the only problem... why can't it be a number? So the error by itself kinda-sorta contradicts itself and requires an additional elementwise error saying a is also the wrong type to clear things up.

tl;dr: the error message isn’t a complete description of the problem, you also need to know what the source type of a is to understand why there’s an error at all

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It makes sense. When rereading it now I see how this is confusing - perhaps the related information should mention the complete source type or it should somehow mention the selected best type based on which this elementwise elaboration is produced.

I'll look into improving this - thanks for the feedback ❤️

@typescript-bot
Copy link
Collaborator

@DanielRosenwasser
The results of the perf run you requested are in!

Here they are:

tsc

Comparison Report - baseline..pr
Metric baseline pr Delta Best Worst p-value
Angular - node (v18.15.0, x64)
Memory used 295,637k (± 0.01%) 295,682k (± 0.01%) +45k (+ 0.02%) 295,637k 295,708k p=0.025 n=6
Parse Time 2.67s (± 0.31%) 2.67s (± 0.28%) ~ 2.66s 2.68s p=0.209 n=6
Bind Time 0.84s (± 1.06%) 0.83s (± 0.76%) ~ 0.82s 0.84s p=0.070 n=6
Check Time 8.25s (± 0.44%) 8.26s (± 0.35%) ~ 8.22s 8.28s p=0.685 n=6
Emit Time 7.09s (± 0.26%) 7.10s (± 0.29%) ~ 7.09s 7.13s p=0.437 n=6
Total Time 18.84s (± 0.31%) 18.86s (± 0.15%) ~ 18.81s 18.89s p=0.325 n=6
Compiler-Unions - node (v18.15.0, x64)
Memory used 193,496k (± 1.54%) 192,545k (± 1.25%) ~ 191,513k 197,474k p=0.575 n=6
Parse Time 1.36s (± 1.46%) 1.35s (± 0.81%) ~ 1.33s 1.36s p=0.397 n=6
Bind Time 0.72s (± 0.00%) 0.72s (± 0.00%) ~ 0.72s 0.72s p=1.000 n=6
Check Time 9.37s (± 0.28%) 9.36s (± 0.44%) ~ 9.31s 9.43s p=0.683 n=6
Emit Time 2.62s (± 0.45%) 2.60s (± 0.51%) -0.02s (- 0.76%) 2.59s 2.62s p=0.039 n=6
Total Time 14.06s (± 0.19%) 14.04s (± 0.32%) ~ 13.96s 14.09s p=0.260 n=6
Monaco - node (v18.15.0, x64)
Memory used 347,470k (± 0.01%) 347,476k (± 0.00%) ~ 347,456k 347,491k p=0.521 n=6
Parse Time 2.47s (± 0.47%) 2.46s (± 1.30%) ~ 2.40s 2.49s p=0.933 n=6
Bind Time 0.92s (± 0.56%) 0.93s (± 1.99%) ~ 0.92s 0.97s p=0.247 n=6
Check Time 6.96s (± 0.47%) 6.95s (± 0.35%) ~ 6.91s 6.98s p=0.627 n=6
Emit Time 4.05s (± 0.56%) 4.05s (± 0.58%) ~ 4.02s 4.08s p=1.000 n=6
Total Time 14.42s (± 0.16%) 14.40s (± 0.34%) ~ 14.33s 14.45s p=0.935 n=6
TFS - node (v18.15.0, x64)
Memory used 302,871k (± 0.01%) 302,863k (± 0.00%) ~ 302,852k 302,879k p=0.688 n=6
Parse Time 2.01s (± 0.75%) 2.01s (± 0.81%) ~ 1.99s 2.04s p=0.415 n=6
Bind Time 1.00s (± 1.22%) 1.00s (± 0.81%) ~ 1.00s 1.02s p=1.000 n=6
Check Time 6.34s (± 0.34%) 6.35s (± 0.37%) ~ 6.33s 6.39s p=0.625 n=6
Emit Time 3.58s (± 0.41%) 3.59s (± 0.81%) ~ 3.56s 3.64s p=0.746 n=6
Total Time 12.94s (± 0.16%) 12.96s (± 0.28%) ~ 12.92s 13.02s p=0.195 n=6
material-ui - node (v18.15.0, x64)
Memory used 511,311k (± 0.01%) 511,281k (± 0.00%) ~ 511,263k 511,312k p=0.575 n=6
Parse Time 2.66s (± 0.60%) 2.66s (± 0.28%) ~ 2.65s 2.67s p=0.676 n=6
Bind Time 0.99s (± 0.84%) 0.99s (± 1.04%) ~ 0.98s 1.01s p=0.788 n=6
Check Time 17.26s (± 0.54%) 17.24s (± 0.22%) ~ 17.19s 17.29s p=1.000 n=6
Emit Time 0.00s (± 0.00%) 0.00s (± 0.00%) ~ 0.00s 0.00s p=1.000 n=6
Total Time 20.92s (± 0.40%) 20.89s (± 0.23%) ~ 20.82s 20.95s p=0.809 n=6
mui-docs - node (v18.15.0, x64)
Memory used 2,294,916k (± 0.00%) 2,294,889k (± 0.00%) ~ 2,294,776k 2,294,977k p=0.521 n=6
Parse Time 12.00s (± 0.86%) 12.06s (± 1.14%) ~ 11.92s 12.30s p=0.521 n=6
Bind Time 2.64s (± 0.54%) 2.64s (± 0.34%) ~ 2.63s 2.65s p=1.000 n=6
Check Time 101.56s (± 0.75%) 101.54s (± 0.70%) ~ 100.57s 102.45s p=0.936 n=6
Emit Time 0.32s (± 0.00%) 0.32s (± 1.28%) ~ 0.31s 0.32s p=0.405 n=6
Total Time 116.53s (± 0.59%) 116.56s (± 0.66%) ~ 115.55s 117.57s p=1.000 n=6
self-build-src - node (v18.15.0, x64)
Memory used 2,406,124k (± 0.02%) 2,406,232k (± 0.03%) ~ 2,405,206k 2,407,111k p=0.689 n=6
Parse Time 5.06s (± 0.95%) 5.06s (± 0.95%) ~ 5.00s 5.11s p=0.810 n=6
Bind Time 1.89s (± 0.99%) 1.88s (± 0.78%) ~ 1.86s 1.90s p=0.808 n=6
Check Time 33.63s (± 0.14%) 33.75s (± 0.49%) ~ 33.47s 33.95s p=0.066 n=6
Emit Time 2.69s (± 1.19%) 2.69s (± 1.50%) ~ 2.64s 2.75s p=0.810 n=6
Total Time 43.29s (± 0.21%) 43.40s (± 0.41%) ~ 43.09s 43.62s p=0.128 n=6
self-compiler - node (v18.15.0, x64)
Memory used 419,243k (± 0.00%) 419,297k (± 0.01%) +55k (+ 0.01%) 419,251k 419,413k p=0.020 n=6
Parse Time 2.80s (± 2.38%) 2.78s (± 1.89%) ~ 2.69s 2.82s p=0.376 n=6
Bind Time 1.10s (± 5.36%) 1.13s (± 6.30%) ~ 1.08s 1.22s p=0.167 n=6
Check Time 15.28s (± 0.25%) 15.28s (± 0.56%) ~ 15.16s 15.41s p=1.000 n=6
Emit Time 1.15s (± 0.90%) 1.14s (± 0.92%) ~ 1.13s 1.16s p=0.801 n=6
Total Time 20.32s (± 0.24%) 20.33s (± 0.46%) ~ 20.19s 20.42s p=0.810 n=6
vscode - node (v18.15.0, x64)
Memory used 2,849,337k (± 0.00%) 2,849,326k (± 0.00%) ~ 2,849,213k 2,849,438k p=0.936 n=6
Parse Time 10.76s (± 0.08%) 10.75s (± 0.25%) ~ 10.72s 10.78s p=0.738 n=6
Bind Time 3.43s (± 0.15%) 3.44s (± 0.31%) ~ 3.42s 3.45s p=0.794 n=6
Check Time 60.59s (± 0.23%) 60.77s (± 0.11%) +0.18s (+ 0.30%) 60.67s 60.84s p=0.029 n=6
Emit Time 16.28s (± 0.43%) 16.28s (± 0.82%) ~ 16.12s 16.47s p=1.000 n=6
Total Time 91.06s (± 0.11%) 91.23s (± 0.18%) ~ 91.02s 91.44s p=0.128 n=6
webpack - node (v18.15.0, x64)
Memory used 396,877k (± 0.01%) 396,889k (± 0.01%) ~ 396,846k 396,981k p=1.000 n=6
Parse Time 3.16s (± 0.54%) 3.17s (± 0.45%) ~ 3.15s 3.19s p=0.287 n=6
Bind Time 1.40s (± 0.37%) 1.40s (± 0.75%) ~ 1.38s 1.41s p=0.794 n=6
Check Time 14.12s (± 0.19%) 14.08s (± 0.40%) ~ 13.99s 14.13s p=0.291 n=6
Emit Time 0.00s (± 0.00%) 0.00s (± 0.00%) ~ 0.00s 0.00s p=1.000 n=6
Total Time 18.67s (± 0.20%) 18.64s (± 0.35%) ~ 18.53s 18.69s p=0.744 n=6
xstate - node (v18.15.0, x64)
Memory used 513,446k (± 0.01%) 513,429k (± 0.01%) ~ 513,377k 513,520k p=0.471 n=6
Parse Time 3.27s (± 0.27%) 3.28s (± 0.30%) ~ 3.27s 3.29s p=0.082 n=6
Bind Time 1.54s (± 0.41%) 1.54s (± 0.35%) ~ 1.54s 1.55s p=0.201 n=6
Check Time 2.87s (± 0.58%) 2.89s (± 0.78%) ~ 2.87s 2.93s p=0.105 n=6
Emit Time 0.08s (± 0.00%) 0.08s (± 7.90%) ~ 0.07s 0.09s p=1.000 n=6
Total Time 7.76s (± 0.34%) 7.80s (± 0.39%) ~ 7.76s 7.85s p=0.065 n=6
System info unknown
Hosts
  • node (v18.15.0, x64)
Scenarios
  • Angular - node (v18.15.0, x64)
  • Compiler-Unions - node (v18.15.0, x64)
  • Monaco - node (v18.15.0, x64)
  • TFS - node (v18.15.0, x64)
  • material-ui - node (v18.15.0, x64)
  • mui-docs - node (v18.15.0, x64)
  • self-build-src - node (v18.15.0, x64)
  • self-compiler - node (v18.15.0, x64)
  • vscode - node (v18.15.0, x64)
  • webpack - node (v18.15.0, x64)
  • xstate - node (v18.15.0, x64)
Benchmark Name Iterations
Current pr 6
Baseline baseline 6

tsserver

Comparison Report - baseline..pr
Metric baseline pr Delta Best Worst p-value
Compiler-UnionsTSServer - node (v18.15.0, x64)
Req 1 - updateOpen 2,351ms (± 0.38%) 2,342ms (± 0.77%) ~ 2,324ms 2,373ms p=0.261 n=6
Req 2 - geterr 5,507ms (± 1.10%) 5,579ms (± 1.12%) ~ 5,496ms 5,653ms p=0.066 n=6
Req 3 - references 327ms (± 1.76%) 325ms (± 1.00%) ~ 322ms 331ms p=0.568 n=6
Req 4 - navto 277ms (± 0.84%) 274ms (± 1.32%) ~ 272ms 279ms p=0.212 n=6
Req 5 - completionInfo count 1,357 (± 0.00%) 1,357 (± 0.00%) ~ 1,357 1,357 p=1.000 n=6
Req 5 - completionInfo 82ms (± 6.45%) 90ms (± 6.65%) 🔻+8ms (+ 9.15%) 80ms 94ms p=0.021 n=6
CompilerTSServer - node (v18.15.0, x64)
Req 1 - updateOpen 2,472ms (± 0.74%) 2,479ms (± 0.76%) ~ 2,454ms 2,509ms p=0.378 n=6
Req 2 - geterr 4,177ms (± 1.73%) 4,226ms (± 1.86%) ~ 4,115ms 4,283ms p=0.298 n=6
Req 3 - references 336ms (± 1.48%) 334ms (± 0.92%) ~ 331ms 340ms p=0.686 n=6
Req 4 - navto 284ms (± 0.43%) 286ms (± 1.29%) ~ 282ms 291ms p=1.000 n=6
Req 5 - completionInfo count 1,519 (± 0.00%) 1,519 (± 0.00%) ~ 1,519 1,519 p=1.000 n=6
Req 5 - completionInfo 86ms (± 7.40%) 81ms (± 6.30%) ~ 77ms 89ms p=0.166 n=6
xstateTSServer - node (v18.15.0, x64)
Req 1 - updateOpen 2,603ms (± 0.55%) 2,610ms (± 0.54%) ~ 2,593ms 2,626ms p=0.572 n=6
Req 2 - geterr 1,736ms (± 2.44%) 1,758ms (± 1.27%) ~ 1,724ms 1,791ms p=0.575 n=6
Req 3 - references 114ms (± 9.19%) 120ms (± 8.94%) ~ 106ms 127ms p=1.000 n=6
Req 4 - navto 370ms (± 0.17%) 371ms (± 0.28%) ~ 369ms 372ms p=0.388 n=6
Req 5 - completionInfo count 2,079 (± 0.00%) 2,079 (± 0.00%) ~ 2,079 2,079 p=1.000 n=6
Req 5 - completionInfo 311ms (± 1.52%) 314ms (± 1.09%) ~ 309ms 317ms p=0.169 n=6
System info unknown
Hosts
  • node (v18.15.0, x64)
Scenarios
  • CompilerTSServer - node (v18.15.0, x64)
  • Compiler-UnionsTSServer - node (v18.15.0, x64)
  • xstateTSServer - node (v18.15.0, x64)
Benchmark Name Iterations
Current pr 6
Baseline baseline 6

startup

Comparison Report - baseline..pr
Metric baseline pr Delta Best Worst p-value
tsc-startup - node (v18.15.0, x64)
Execution time 153.89ms (± 0.19%) 153.80ms (± 0.18%) -0.09ms (- 0.06%) 152.88ms 157.83ms p=0.004 n=600
tsserver-startup - node (v18.15.0, x64)
Execution time 229.96ms (± 0.15%) 229.86ms (± 0.17%) -0.11ms (- 0.05%) 228.32ms 235.35ms p=0.000 n=600
tsserverlibrary-startup - node (v18.15.0, x64)
Execution time 231.83ms (± 0.19%) 232.02ms (± 0.19%) +0.19ms (+ 0.08%) 230.47ms 236.77ms p=0.000 n=600
typescript-startup - node (v18.15.0, x64)
Execution time 231.10ms (± 0.18%) 231.13ms (± 0.18%) ~ 229.70ms 237.75ms p=0.597 n=600
System info unknown
Hosts
  • node (v18.15.0, x64)
Scenarios
  • tsc-startup - node (v18.15.0, x64)
  • tsserver-startup - node (v18.15.0, x64)
  • tsserverlibrary-startup - node (v18.15.0, x64)
  • typescript-startup - node (v18.15.0, x64)
Benchmark Name Iterations
Current pr 6
Baseline baseline 6

Developer Information:

Download Benchmarks

@sandersn sandersn added this to Not started in PR Backlog Mar 8, 2024
@sandersn sandersn requested a review from weswigham March 20, 2024 20:49
@typescript-bot typescript-bot added For Backlog Bug PRs that fix a backlog bug and removed For Uncommitted Bug PR for untriaged, rejected, closed or missing bug labels Mar 20, 2024
@sandersn sandersn moved this from Not started to Waiting on reviewers in PR Backlog Mar 20, 2024
…s-best-type-obj-literal

# Conflicts:
#	src/compiler/utilities.ts
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
For Backlog Bug PRs that fix a backlog bug
Projects
PR Backlog
  
Waiting on reviewers
Development

Successfully merging this pull request may close these issues.

Wrong elementwise error location on optional object property that allows arrays too
5 participants