mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-29 16:29:19 -05:00
Retain CheckFlags.Late on symbols manufactured based on Late-bound symbols (#42205)
This commit is contained in:
@@ -10630,6 +10630,10 @@ namespace ts {
|
||||
return type;
|
||||
}
|
||||
|
||||
function getIsLateCheckFlag(s: Symbol): CheckFlags {
|
||||
return getCheckFlags(s) & CheckFlags.Late;
|
||||
}
|
||||
|
||||
/** Resolve the members of a mapped type { [P in K]: T } */
|
||||
function resolveMappedTypeMembers(type: MappedType) {
|
||||
const members: SymbolTable = createSymbolTable();
|
||||
@@ -10688,8 +10692,9 @@ namespace ts {
|
||||
const isReadonly = !!(templateModifiers & MappedTypeModifiers.IncludeReadonly ||
|
||||
!(templateModifiers & MappedTypeModifiers.ExcludeReadonly) && modifiersProp && isReadonlySymbol(modifiersProp));
|
||||
const stripOptional = strictNullChecks && !isOptional && modifiersProp && modifiersProp.flags & SymbolFlags.Optional;
|
||||
const lateFlag: CheckFlags = modifiersProp ? getIsLateCheckFlag(modifiersProp) : 0;
|
||||
const prop = <MappedSymbol>createSymbol(SymbolFlags.Property | (isOptional ? SymbolFlags.Optional : 0), propName,
|
||||
CheckFlags.Mapped | (isReadonly ? CheckFlags.Readonly : 0) | (stripOptional ? CheckFlags.StripOptional : 0));
|
||||
lateFlag | CheckFlags.Mapped | (isReadonly ? CheckFlags.Readonly : 0) | (stripOptional ? CheckFlags.StripOptional : 0));
|
||||
prop.mappedType = type;
|
||||
prop.nameType = propNameType;
|
||||
prop.keyType = keyType;
|
||||
@@ -14666,7 +14671,7 @@ namespace ts {
|
||||
else if (isSpreadableProperty(prop)) {
|
||||
const isSetonlyAccessor = prop.flags & SymbolFlags.SetAccessor && !(prop.flags & SymbolFlags.GetAccessor);
|
||||
const flags = SymbolFlags.Property | SymbolFlags.Optional;
|
||||
const result = createSymbol(flags, prop.escapedName, readonly ? CheckFlags.Readonly : 0);
|
||||
const result = createSymbol(flags, prop.escapedName, getIsLateCheckFlag(prop) | (readonly ? CheckFlags.Readonly : 0));
|
||||
result.type = isSetonlyAccessor ? undefinedType : getTypeOfSymbol(prop);
|
||||
result.declarations = prop.declarations;
|
||||
result.nameType = getSymbolLinks(prop).nameType;
|
||||
@@ -14814,7 +14819,7 @@ namespace ts {
|
||||
return prop;
|
||||
}
|
||||
const flags = SymbolFlags.Property | (prop.flags & SymbolFlags.Optional);
|
||||
const result = createSymbol(flags, prop.escapedName, readonly ? CheckFlags.Readonly : 0);
|
||||
const result = createSymbol(flags, prop.escapedName, getIsLateCheckFlag(prop) | (readonly ? CheckFlags.Readonly : 0));
|
||||
result.type = isSetonlyAccessor ? undefinedType : getTypeOfSymbol(prop);
|
||||
result.declarations = prop.declarations;
|
||||
result.nameType = getSymbolLinks(prop).nameType;
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
tests/cases/compiler/index.ts(3,14): error TS4023: Exported variable 'spread' has or is using name 'SYMBOL' from external module "tests/cases/compiler/bug" but cannot be named.
|
||||
|
||||
|
||||
==== tests/cases/compiler/bug.ts (0 errors) ====
|
||||
export const SYMBOL = Symbol()
|
||||
|
||||
export interface Interface {
|
||||
readonly [SYMBOL]: string; // remove readonly and @showEmit to see the expected error
|
||||
}
|
||||
|
||||
export function createInstance(): Interface {
|
||||
return {
|
||||
[SYMBOL]: ''
|
||||
}
|
||||
}
|
||||
|
||||
==== tests/cases/compiler/index.ts (1 errors) ====
|
||||
import { createInstance } from './bug'
|
||||
|
||||
export const spread = {
|
||||
~~~~~~
|
||||
!!! error TS4023: Exported variable 'spread' has or is using name 'SYMBOL' from external module "tests/cases/compiler/bug" but cannot be named.
|
||||
...createInstance(),
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
//// [tests/cases/compiler/declarationEmitReadonlyComputedProperty.ts] ////
|
||||
|
||||
//// [bug.ts]
|
||||
export const SYMBOL = Symbol()
|
||||
|
||||
export interface Interface {
|
||||
readonly [SYMBOL]: string; // remove readonly and @showEmit to see the expected error
|
||||
}
|
||||
|
||||
export function createInstance(): Interface {
|
||||
return {
|
||||
[SYMBOL]: ''
|
||||
}
|
||||
}
|
||||
|
||||
//// [index.ts]
|
||||
import { createInstance } from './bug'
|
||||
|
||||
export const spread = {
|
||||
...createInstance(),
|
||||
}
|
||||
|
||||
//// [bug.js]
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
exports.createInstance = exports.SYMBOL = void 0;
|
||||
exports.SYMBOL = Symbol();
|
||||
function createInstance() {
|
||||
var _a;
|
||||
return _a = {},
|
||||
_a[exports.SYMBOL] = '',
|
||||
_a;
|
||||
}
|
||||
exports.createInstance = createInstance;
|
||||
//// [index.js]
|
||||
"use strict";
|
||||
var __assign = (this && this.__assign) || function () {
|
||||
__assign = Object.assign || function(t) {
|
||||
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
||||
s = arguments[i];
|
||||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
||||
t[p] = s[p];
|
||||
}
|
||||
return t;
|
||||
};
|
||||
return __assign.apply(this, arguments);
|
||||
};
|
||||
exports.__esModule = true;
|
||||
exports.spread = void 0;
|
||||
var bug_1 = require("./bug");
|
||||
exports.spread = __assign({}, bug_1.createInstance());
|
||||
|
||||
|
||||
//// [bug.d.ts]
|
||||
export declare const SYMBOL: unique symbol;
|
||||
export interface Interface {
|
||||
readonly [SYMBOL]: string;
|
||||
}
|
||||
export declare function createInstance(): Interface;
|
||||
@@ -0,0 +1,34 @@
|
||||
=== tests/cases/compiler/bug.ts ===
|
||||
export const SYMBOL = Symbol()
|
||||
>SYMBOL : Symbol(SYMBOL, Decl(bug.ts, 0, 12))
|
||||
>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --))
|
||||
|
||||
export interface Interface {
|
||||
>Interface : Symbol(Interface, Decl(bug.ts, 0, 30))
|
||||
|
||||
readonly [SYMBOL]: string; // remove readonly and @showEmit to see the expected error
|
||||
>[SYMBOL] : Symbol(Interface[SYMBOL], Decl(bug.ts, 2, 28))
|
||||
>SYMBOL : Symbol(SYMBOL, Decl(bug.ts, 0, 12))
|
||||
}
|
||||
|
||||
export function createInstance(): Interface {
|
||||
>createInstance : Symbol(createInstance, Decl(bug.ts, 4, 1))
|
||||
>Interface : Symbol(Interface, Decl(bug.ts, 0, 30))
|
||||
|
||||
return {
|
||||
[SYMBOL]: ''
|
||||
>[SYMBOL] : Symbol([SYMBOL], Decl(bug.ts, 7, 10))
|
||||
>SYMBOL : Symbol(SYMBOL, Decl(bug.ts, 0, 12))
|
||||
}
|
||||
}
|
||||
|
||||
=== tests/cases/compiler/index.ts ===
|
||||
import { createInstance } from './bug'
|
||||
>createInstance : Symbol(createInstance, Decl(index.ts, 0, 8))
|
||||
|
||||
export const spread = {
|
||||
>spread : Symbol(spread, Decl(index.ts, 2, 12))
|
||||
|
||||
...createInstance(),
|
||||
>createInstance : Symbol(createInstance, Decl(index.ts, 0, 8))
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
=== tests/cases/compiler/bug.ts ===
|
||||
export const SYMBOL = Symbol()
|
||||
>SYMBOL : unique symbol
|
||||
>Symbol() : unique symbol
|
||||
>Symbol : SymbolConstructor
|
||||
|
||||
export interface Interface {
|
||||
readonly [SYMBOL]: string; // remove readonly and @showEmit to see the expected error
|
||||
>[SYMBOL] : string
|
||||
>SYMBOL : unique symbol
|
||||
}
|
||||
|
||||
export function createInstance(): Interface {
|
||||
>createInstance : () => Interface
|
||||
|
||||
return {
|
||||
>{ [SYMBOL]: '' } : { [SYMBOL]: string; }
|
||||
|
||||
[SYMBOL]: ''
|
||||
>[SYMBOL] : string
|
||||
>SYMBOL : unique symbol
|
||||
>'' : ""
|
||||
}
|
||||
}
|
||||
|
||||
=== tests/cases/compiler/index.ts ===
|
||||
import { createInstance } from './bug'
|
||||
>createInstance : () => import("tests/cases/compiler/bug").Interface
|
||||
|
||||
export const spread = {
|
||||
>spread : { [SYMBOL]: string; }
|
||||
>{ ...createInstance(),} : { [SYMBOL]: string; }
|
||||
|
||||
...createInstance(),
|
||||
>createInstance() : import("tests/cases/compiler/bug").Interface
|
||||
>createInstance : () => import("tests/cases/compiler/bug").Interface
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
// @declaration: true
|
||||
// @lib: es2015
|
||||
|
||||
// @filename: bug.ts
|
||||
export const SYMBOL = Symbol()
|
||||
|
||||
export interface Interface {
|
||||
readonly [SYMBOL]: string; // remove readonly and @showEmit to see the expected error
|
||||
}
|
||||
|
||||
export function createInstance(): Interface {
|
||||
return {
|
||||
[SYMBOL]: ''
|
||||
}
|
||||
}
|
||||
|
||||
// @filename: index.ts
|
||||
import { createInstance } from './bug'
|
||||
|
||||
export const spread = {
|
||||
...createInstance(),
|
||||
}
|
||||
Reference in New Issue
Block a user