Reinstate constraint check for template literal types (#43661)

* Add missing constraint check for template literal types

* Add regression test
This commit is contained in:
Anders Hejlsberg 2021-04-13 12:17:55 -10:00 committed by GitHub
parent 5a6a499d0e
commit 5977233fd1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 95 additions and 0 deletions

View File

@ -18420,6 +18420,16 @@ namespace ts {
return result;
}
}
else if (source.flags & TypeFlags.TemplateLiteral) {
if (!(target.flags & TypeFlags.TemplateLiteral)) {
const baseConstraint = getBaseConstraintOfType(source);
const constraint = baseConstraint && baseConstraint !== source ? baseConstraint : stringType;
if (result = isRelatedTo(constraint, target, reportErrors)) {
resetErrorInfo(saveErrorInfo);
return result;
}
}
}
else if (source.flags & TypeFlags.StringMapping) {
if (target.flags & TypeFlags.StringMapping && (<StringMappingType>source).symbol === (<StringMappingType>target).symbol) {
if (result = isRelatedTo((<StringMappingType>source).type, (<StringMappingType>target).type, reportErrors)) {

View File

@ -126,4 +126,16 @@ tests/cases/conformance/types/literal/templateLiteralTypes3.ts(74,5): error TS23
const value2 = "abc";
const templated2: Templated = `${value2} abc` as const;
// Repro from #43620
type Prefixes = "foo" | "bar";
type AllPrefixData = "foo:baz" | "bar:baz";
type PrefixData<P extends Prefixes> = `${P}:baz`;
interface ITest<P extends Prefixes, E extends AllPrefixData = PrefixData<P>> {
blah: string;
}

View File

@ -104,6 +104,18 @@ const templated1: Templated = `${value1} abc` as const;
const value2 = "abc";
const templated2: Templated = `${value2} abc` as const;
// Repro from #43620
type Prefixes = "foo" | "bar";
type AllPrefixData = "foo:baz" | "bar:baz";
type PrefixData<P extends Prefixes> = `${P}:baz`;
interface ITest<P extends Prefixes, E extends AllPrefixData = PrefixData<P>> {
blah: string;
}
//// [templateLiteralTypes3.js]
@ -198,3 +210,9 @@ declare const value1: string;
declare const templated1: Templated;
declare const value2 = "abc";
declare const templated2: Templated;
declare type Prefixes = "foo" | "bar";
declare type AllPrefixData = "foo:baz" | "bar:baz";
declare type PrefixData<P extends Prefixes> = `${P}:baz`;
interface ITest<P extends Prefixes, E extends AllPrefixData = PrefixData<P>> {
blah: string;
}

View File

@ -342,3 +342,30 @@ const templated2: Templated = `${value2} abc` as const;
>Templated : Symbol(Templated, Decl(templateLiteralTypes3.ts, 93, 29))
>value2 : Symbol(value2, Decl(templateLiteralTypes3.ts, 103, 5))
// Repro from #43620
type Prefixes = "foo" | "bar";
>Prefixes : Symbol(Prefixes, Decl(templateLiteralTypes3.ts, 104, 55))
type AllPrefixData = "foo:baz" | "bar:baz";
>AllPrefixData : Symbol(AllPrefixData, Decl(templateLiteralTypes3.ts, 108, 30))
type PrefixData<P extends Prefixes> = `${P}:baz`;
>PrefixData : Symbol(PrefixData, Decl(templateLiteralTypes3.ts, 110, 43))
>P : Symbol(P, Decl(templateLiteralTypes3.ts, 112, 16))
>Prefixes : Symbol(Prefixes, Decl(templateLiteralTypes3.ts, 104, 55))
>P : Symbol(P, Decl(templateLiteralTypes3.ts, 112, 16))
interface ITest<P extends Prefixes, E extends AllPrefixData = PrefixData<P>> {
>ITest : Symbol(ITest, Decl(templateLiteralTypes3.ts, 112, 49))
>P : Symbol(P, Decl(templateLiteralTypes3.ts, 114, 16))
>Prefixes : Symbol(Prefixes, Decl(templateLiteralTypes3.ts, 104, 55))
>E : Symbol(E, Decl(templateLiteralTypes3.ts, 114, 35))
>AllPrefixData : Symbol(AllPrefixData, Decl(templateLiteralTypes3.ts, 108, 30))
>PrefixData : Symbol(PrefixData, Decl(templateLiteralTypes3.ts, 110, 43))
>P : Symbol(P, Decl(templateLiteralTypes3.ts, 114, 16))
blah: string;
>blah : Symbol(ITest.blah, Decl(templateLiteralTypes3.ts, 114, 78))
}

View File

@ -363,3 +363,19 @@ const templated2: Templated = `${value2} abc` as const;
>`${value2} abc` : "abc abc"
>value2 : "abc"
// Repro from #43620
type Prefixes = "foo" | "bar";
>Prefixes : Prefixes
type AllPrefixData = "foo:baz" | "bar:baz";
>AllPrefixData : AllPrefixData
type PrefixData<P extends Prefixes> = `${P}:baz`;
>PrefixData : `${P}:baz`
interface ITest<P extends Prefixes, E extends AllPrefixData = PrefixData<P>> {
blah: string;
>blah : string
}

View File

@ -106,3 +106,15 @@ const templated1: Templated = `${value1} abc` as const;
const value2 = "abc";
const templated2: Templated = `${value2} abc` as const;
// Repro from #43620
type Prefixes = "foo" | "bar";
type AllPrefixData = "foo:baz" | "bar:baz";
type PrefixData<P extends Prefixes> = `${P}:baz`;
interface ITest<P extends Prefixes, E extends AllPrefixData = PrefixData<P>> {
blah: string;
}