Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 7d823ae

Browse filesBrowse files
committed
Merge branch 'main' of https://github.com/microsoft/TypeScript into feat/51086
2 parents 659c141 + aa2781d commit 7d823ae
Copy full SHA for 7d823ae

9 files changed

+131-4Lines changed: 131 additions & 4 deletions
Expand file treeCollapse file tree
Open diff view settings
Collapse file

‎src/compiler/checker.ts‎

Copy file name to clipboardExpand all lines: src/compiler/checker.ts
+18-4Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17609,6 +17609,13 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
1760917609
return getTypeOfSymbol(symbol); // intentionally doesn't use resolved symbol so type is cached as expected on the alias
1761017610
}
1761117611
else {
17612+
const type = tryGetDeclaredTypeOfSymbol(resolvedSymbol); // call this first to ensure typeParameters is populated (if applicable)
17613+
const typeParameters = type && getTypeParametersForTypeAndSymbol(type, resolvedSymbol);
17614+
if (node.typeArguments && typeParameters) {
17615+
addLazyDiagnostic(() => {
17616+
checkTypeArgumentConstraints(node, typeParameters);
17617+
});
17618+
}
1761217619
return getTypeReferenceType(node, resolvedSymbol); // getTypeReferenceType doesn't handle aliases - it must get the resolved symbol
1761317620
}
1761417621
}
@@ -37276,12 +37283,12 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
3727637283
return getEffectiveTypeArguments(node, typeParameters)[index];
3727737284
}
3727837285

37279-
function getEffectiveTypeArguments(node: TypeReferenceNode | ExpressionWithTypeArguments, typeParameters: readonly TypeParameter[]): Type[] {
37286+
function getEffectiveTypeArguments(node: TypeReferenceNode | ExpressionWithTypeArguments | NodeWithTypeArguments, typeParameters: readonly TypeParameter[]): Type[] {
3728037287
return fillMissingTypeArguments(map(node.typeArguments!, getTypeFromTypeNode), typeParameters,
3728137288
getMinTypeArgumentCount(typeParameters), isInJSFile(node));
3728237289
}
3728337290

37284-
function checkTypeArgumentConstraints(node: TypeReferenceNode | ExpressionWithTypeArguments, typeParameters: readonly TypeParameter[]): boolean {
37291+
function checkTypeArgumentConstraints(node: TypeReferenceNode | ExpressionWithTypeArguments | NodeWithTypeArguments, typeParameters: readonly TypeParameter[]): boolean {
3728537292
let typeArguments: Type[] | undefined;
3728637293
let mapper: TypeMapper | undefined;
3728737294
let result = true;
@@ -37302,13 +37309,20 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
3730237309
return result;
3730337310
}
3730437311

37312+
function getTypeParametersForTypeAndSymbol(type: Type, symbol: Symbol) {
37313+
if (!isErrorType(type)) {
37314+
return symbol.flags & SymbolFlags.TypeAlias && getSymbolLinks(symbol).typeParameters ||
37315+
(getObjectFlags(type) & ObjectFlags.Reference ? (type as TypeReference).target.localTypeParameters : undefined);
37316+
}
37317+
return undefined;
37318+
}
37319+
3730537320
function getTypeParametersForTypeReference(node: TypeReferenceNode | ExpressionWithTypeArguments) {
3730637321
const type = getTypeFromTypeReference(node);
3730737322
if (!isErrorType(type)) {
3730837323
const symbol = getNodeLinks(node).resolvedSymbol;
3730937324
if (symbol) {
37310-
return symbol.flags & SymbolFlags.TypeAlias && getSymbolLinks(symbol).typeParameters ||
37311-
(getObjectFlags(type) & ObjectFlags.Reference ? (type as TypeReference).target.localTypeParameters : undefined);
37325+
return getTypeParametersForTypeAndSymbol(type, symbol);
3731237326
}
3731337327
}
3731437328
return undefined;
Collapse file
+12Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
tests/cases/compiler/file2.ts(1,37): error TS2344: Type 'T' does not satisfy the constraint 'string'.
2+
3+
4+
==== tests/cases/compiler/file1.ts (0 errors) ====
5+
export type Foo<T extends string> = { foo: T }
6+
7+
==== tests/cases/compiler/file2.ts (1 errors) ====
8+
type Bar<T> = import('./file1').Foo<T>;
9+
~
10+
!!! error TS2344: Type 'T' does not satisfy the constraint 'string'.
11+
!!! related TS2208 tests/cases/compiler/file2.ts:1:10: This type parameter might need an `extends string` constraint.
12+
Collapse file
+14Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
=== tests/cases/compiler/file1.ts ===
2+
export type Foo<T extends string> = { foo: T }
3+
>Foo : Symbol(Foo, Decl(file1.ts, 0, 0))
4+
>T : Symbol(T, Decl(file1.ts, 0, 16))
5+
>foo : Symbol(foo, Decl(file1.ts, 0, 37))
6+
>T : Symbol(T, Decl(file1.ts, 0, 16))
7+
8+
=== tests/cases/compiler/file2.ts ===
9+
type Bar<T> = import('./file1').Foo<T>;
10+
>Bar : Symbol(Bar, Decl(file2.ts, 0, 0))
11+
>T : Symbol(T, Decl(file2.ts, 0, 9))
12+
>Foo : Symbol(Foo, Decl(file1.ts, 0, 0))
13+
>T : Symbol(T, Decl(file2.ts, 0, 9))
14+
Collapse file
+9Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
=== tests/cases/compiler/file1.ts ===
2+
export type Foo<T extends string> = { foo: T }
3+
>Foo : Foo<T>
4+
>foo : T
5+
6+
=== tests/cases/compiler/file2.ts ===
7+
type Bar<T> = import('./file1').Foo<T>;
8+
>Bar : Bar<T>
9+
Collapse file
+20Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
tests/cases/compiler/file2.js(3,36): error TS2344: Type 'T' does not satisfy the constraint 'string'.
2+
3+
4+
==== tests/cases/compiler/file1.js (0 errors) ====
5+
/**
6+
* @template {string} T
7+
* @typedef {{ foo: T }} Foo
8+
*/
9+
10+
export default {};
11+
12+
==== tests/cases/compiler/file2.js (1 errors) ====
13+
/**
14+
* @template T
15+
* @typedef {import('./file1').Foo<T>} Bar
16+
~
17+
!!! error TS2344: Type 'T' does not satisfy the constraint 'string'.
18+
!!! related TS2208 tests/cases/compiler/file2.js:2:14: This type parameter might need an `extends string` constraint.
19+
*/
20+
Collapse file
+16Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
=== tests/cases/compiler/file1.js ===
2+
3+
/**
4+
* @template {string} T
5+
* @typedef {{ foo: T }} Foo
6+
*/
7+
8+
export default {};
9+
10+
=== tests/cases/compiler/file2.js ===
11+
12+
/**
13+
* @template T
14+
* @typedef {import('./file1').Foo<T>} Bar
15+
*/
16+
Collapse file
+16Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
=== tests/cases/compiler/file1.js ===
2+
/**
3+
* @template {string} T
4+
* @typedef {{ foo: T }} Foo
5+
*/
6+
7+
export default {};
8+
>{} : {}
9+
10+
=== tests/cases/compiler/file2.js ===
11+
12+
/**
13+
* @template T
14+
* @typedef {import('./file1').Foo<T>} Bar
15+
*/
16+
Collapse file
+7Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// @noEmit: true
2+
// @filename: file1.ts
3+
export type Foo<T extends string> = { foo: T }
4+
5+
// @noEmit: true
6+
// @filename: file2.ts
7+
type Bar<T> = import('./file1').Foo<T>;
Collapse file
+19Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// @allowJs: true
2+
// @checkJs: true
3+
// @noEmit: true
4+
// @filename: file1.js
5+
/**
6+
* @template {string} T
7+
* @typedef {{ foo: T }} Foo
8+
*/
9+
10+
export default {};
11+
12+
// @allowJs: true
13+
// @checkJs: true
14+
// @noEmit: true
15+
// @filename: file2.js
16+
/**
17+
* @template T
18+
* @typedef {import('./file1').Foo<T>} Bar
19+
*/

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.