Skip to content

Commit

Permalink
Avoid expensive relationship checking in mapped type member resolution (
Browse files Browse the repository at this point in the history
microsoft#36754)

* Avoid expensive relationship checking in mapped type member resolution

* Accept new baselines
  • Loading branch information
ahejlsberg committed Feb 12, 2020
1 parent e435054 commit 7a1c5b7
Show file tree
Hide file tree
Showing 6 changed files with 23 additions and 23 deletions.
4 changes: 2 additions & 2 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9590,7 +9590,7 @@ namespace ts {
// When creating an optional property in strictNullChecks mode, if 'undefined' isn't assignable to the
// type, we include 'undefined' in the type. Similarly, when creating a non-optional property in strictNullChecks
// mode, if the underlying property is optional we remove 'undefined' from the type.
prop.type = strictNullChecks && isOptional && !isTypeAssignableTo(undefinedType, propType) ? getOptionalType(propType) :
prop.type = strictNullChecks && isOptional && !maybeTypeOfKind(propType, TypeFlags.Undefined | TypeFlags.Void) ? getOptionalType(propType) :
strictNullChecks && !isOptional && modifiersProp && modifiersProp.flags & SymbolFlags.Optional ? getTypeWithFacts(propType, TypeFacts.NEUndefined) :
propType;
if (modifiersProp) {
Expand Down Expand Up @@ -13695,7 +13695,7 @@ namespace ts {
const templateMapper = combineTypeMappers(mapper, createTypeMapper([getTypeParameterFromMappedType(type)], [key]));
const propType = instantiateType(getTemplateTypeFromMappedType(<MappedType>type.target || type), templateMapper);
const modifiers = getMappedTypeModifiers(type);
return strictNullChecks && modifiers & MappedTypeModifiers.IncludeOptional && !isTypeAssignableTo(undefinedType, propType) ? getOptionalType(propType) :
return strictNullChecks && modifiers & MappedTypeModifiers.IncludeOptional && !maybeTypeOfKind(propType, TypeFlags.Undefined | TypeFlags.Void) ? getOptionalType(propType) :
strictNullChecks && modifiers & MappedTypeModifiers.ExcludeOptional && isOptional ? getTypeWithFacts(propType, TypeFacts.NEUndefined) :
propType;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,20 +18,20 @@ class C<T extends Options> {
>method : () => void

let { a, b } = this.foo;
>a : T["a"]
>a : T["a"] | undefined
>b : T["b"]
>this.foo : { [P in keyof T]: T[P]; }
>this : this
>foo : { [P in keyof T]: T[P]; }

!(a && b);
>!(a && b) : false
>(a && b) : T["b"]
>a && b : T["b"]
>a : T["a"]
>!(a && b) : boolean
>(a && b) : T["b"] | undefined
>a && b : T["b"] | undefined
>a : T["a"] | undefined
>b : T["b"]

a;
>a : T["a"]
>a : T["a"] | undefined
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,11 @@ class Test<T extends A> {
this.attrs.params!.name;
>this.attrs.params!.name : any
>this.attrs.params! : T["params"]
>this.attrs.params : T["params"]
>this.attrs.params : T["params"] | undefined
>this.attrs : Readonly<T>
>this : this
>attrs : Readonly<T>
>params : T["params"]
>params : T["params"] | undefined
>name : any
}
}
Expand Down Expand Up @@ -66,10 +66,10 @@ class Test2<T extends A> {

return this.attrs.params!; // Return type should maintain relationship with `T` after being not-null-asserted, ideally
>this.attrs.params! : T["params"]
>this.attrs.params : T["params"]
>this.attrs.params : T["params"] | undefined
>this.attrs : Readonly<T>
>this : this
>attrs : Readonly<T>
>params : T["params"]
>params : T["params"] | undefined
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ class Test<T extends A> {
this.attrs.params!.name;
>this.attrs.params!.name : string
>this.attrs.params! : NonNullable<T["params"]>
>this.attrs.params : T["params"]
>this.attrs.params : T["params"] | undefined
>this.attrs : Readonly<T>
>this : this
>attrs : Readonly<T>
>params : T["params"]
>params : T["params"] | undefined
>name : string
}
}
Expand Down Expand Up @@ -63,10 +63,10 @@ class Test2<T extends A> {

return this.attrs.params!; // Return type should maintain relationship with `T` after being not-null-asserted, ideally
>this.attrs.params! : NonNullable<T["params"]>
>this.attrs.params : T["params"]
>this.attrs.params : T["params"] | undefined
>this.attrs : Readonly<T>
>this : this
>attrs : Readonly<T>
>params : T["params"]
>params : T["params"] | undefined
}
}
6 changes: 3 additions & 3 deletions tests/baselines/reference/typeVariableTypeGuards.types
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,12 @@ class A<P extends Partial<Foo>> {
>doSomething : () => void

this.props.foo && this.props.foo()
>this.props.foo && this.props.foo() : void
>this.props.foo : P["foo"]
>this.props.foo && this.props.foo() : void | undefined
>this.props.foo : P["foo"] | undefined
>this.props : Readonly<P>
>this : this
>props : Readonly<P>
>foo : P["foo"]
>foo : P["foo"] | undefined
>this.props.foo() : void
>this.props.foo : () => void
>this.props : Readonly<P>
Expand Down
8 changes: 4 additions & 4 deletions tests/baselines/reference/voidReturnIndexUnionInference.types
Original file line number Diff line number Diff line change
Expand Up @@ -43,19 +43,19 @@ function bad<P extends Props>(props: Readonly<P>) {
safeInvoke(props.onFoo, "blah");
>safeInvoke(props.onFoo, "blah") : boolean | undefined
>safeInvoke : <A1, R>(func: ((arg1: A1) => R) | null | undefined, arg1: A1) => R | undefined
>props.onFoo : P["onFoo"]
>props.onFoo : P["onFoo"] | undefined
>props : Readonly<P>
>onFoo : P["onFoo"]
>onFoo : P["onFoo"] | undefined
>"blah" : "blah"

// ERROR HERE!!!
// Type R in signature of safeInvoke incorrectly inferred as {} instead of void!
safeInvoke(props.onBar, "blah");
>safeInvoke(props.onBar, "blah") : void | undefined
>safeInvoke : <A1, R>(func: ((arg1: A1) => R) | null | undefined, arg1: A1) => R | undefined
>props.onBar : P["onBar"]
>props.onBar : P["onBar"] | undefined
>props : Readonly<P>
>onBar : P["onBar"]
>onBar : P["onBar"] | undefined
>"blah" : "blah"
}

0 comments on commit 7a1c5b7

Please sign in to comment.