mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-09 02:30:15 -06:00
Produce wide index signatures from the spread of an index signature
This commit is contained in:
parent
8b43f5bbe3
commit
d088733b24
@ -13435,6 +13435,26 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
return emptyArray;
|
||||
}
|
||||
|
||||
function getSpreadIndexInfos(left: Type, right: Type): IndexInfo[] {
|
||||
const rightInfos = getIndexInfosOfType(right);
|
||||
if (!rightInfos.length) return emptyArray;
|
||||
const leftInfos = getIndexInfosOfType(left);
|
||||
const leftProperties = getPropertiesOfType(left);
|
||||
const result: IndexInfo[] = [];
|
||||
for (const rightInfo of rightInfos) {
|
||||
const indexType = rightInfo.keyType;
|
||||
const leftInfo = findIndexInfo(leftInfos, indexType);
|
||||
const types = leftInfo ? [leftInfo.type, rightInfo.type] : [rightInfo.type];
|
||||
for (const prop of leftProperties) {
|
||||
if (isApplicableIndexType(getNameTypeOfPropertyName(prop.escapedName), indexType)) {
|
||||
types.push(getTypeOfSymbol(prop));
|
||||
}
|
||||
}
|
||||
result.push(createIndexInfo(indexType, getUnionType(types), leftInfo && leftInfo.isReadonly || rightInfo.isReadonly));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function resolveUnionTypeMembers(type: UnionType) {
|
||||
// The members and properties collections are empty for union types. To get all properties of a union
|
||||
// type use getPropertiesOfType (only the language service uses this).
|
||||
@ -14888,7 +14908,11 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
}
|
||||
|
||||
function getApplicableIndexInfoForName(type: Type, name: __String): IndexInfo | undefined {
|
||||
return getApplicableIndexInfo(type, isLateBoundName(name) ? esSymbolType : getStringLiteralType(unescapeLeadingUnderscores(name)));
|
||||
return getApplicableIndexInfo(type, getNameTypeOfPropertyName(name));
|
||||
}
|
||||
|
||||
function getNameTypeOfPropertyName(name: __String): Type {
|
||||
return isLateBoundName(name) ? esSymbolType : getStringLiteralType(unescapeLeadingUnderscores(name));
|
||||
}
|
||||
|
||||
// Return list of type parameters with duplicates removed (duplicate identifier errors are generated in the actual
|
||||
@ -18793,7 +18817,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
|
||||
const members = createSymbolTable();
|
||||
const skippedPrivateMembers = new Set<__String>();
|
||||
const indexInfos = left === emptyObjectType ? getIndexInfosOfType(right) : getUnionIndexInfos([left, right]);
|
||||
const indexInfos = left === emptyObjectType ? getIndexInfosOfType(right) : getSpreadIndexInfos(left, right);
|
||||
|
||||
for (const rightProp of getPropertiesOfType(right)) {
|
||||
if (getDeclarationModifierFlagsFromSymbol(rightProp) & (ModifierFlags.Private | ModifierFlags.Protected)) {
|
||||
|
||||
15
tests/baselines/reference/spreadIndexSignature.js
Normal file
15
tests/baselines/reference/spreadIndexSignature.js
Normal file
@ -0,0 +1,15 @@
|
||||
//// [tests/cases/compiler/spreadIndexSignature.ts] ////
|
||||
|
||||
//// [spreadIndexSignature.ts]
|
||||
declare const strings: Record<string, string>;
|
||||
declare const symbols: Record<symbol, string>;
|
||||
|
||||
const o1 = { a: 1, ...strings };
|
||||
const o2 = { [Symbol.iterator]: 1, ...strings };
|
||||
const o3 = { [Symbol.iterator]: 1, ...symbols };
|
||||
|
||||
|
||||
//// [spreadIndexSignature.js]
|
||||
const o1 = { a: 1, ...strings };
|
||||
const o2 = { [Symbol.iterator]: 1, ...strings };
|
||||
const o3 = { [Symbol.iterator]: 1, ...symbols };
|
||||
32
tests/baselines/reference/spreadIndexSignature.symbols
Normal file
32
tests/baselines/reference/spreadIndexSignature.symbols
Normal file
@ -0,0 +1,32 @@
|
||||
//// [tests/cases/compiler/spreadIndexSignature.ts] ////
|
||||
|
||||
=== spreadIndexSignature.ts ===
|
||||
declare const strings: Record<string, string>;
|
||||
>strings : Symbol(strings, Decl(spreadIndexSignature.ts, 0, 13))
|
||||
>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --))
|
||||
|
||||
declare const symbols: Record<symbol, string>;
|
||||
>symbols : Symbol(symbols, Decl(spreadIndexSignature.ts, 1, 13))
|
||||
>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --))
|
||||
|
||||
const o1 = { a: 1, ...strings };
|
||||
>o1 : Symbol(o1, Decl(spreadIndexSignature.ts, 3, 5))
|
||||
>a : Symbol(a, Decl(spreadIndexSignature.ts, 3, 12))
|
||||
>strings : Symbol(strings, Decl(spreadIndexSignature.ts, 0, 13))
|
||||
|
||||
const o2 = { [Symbol.iterator]: 1, ...strings };
|
||||
>o2 : Symbol(o2, Decl(spreadIndexSignature.ts, 4, 5))
|
||||
>[Symbol.iterator] : Symbol([Symbol.iterator], Decl(spreadIndexSignature.ts, 4, 12))
|
||||
>Symbol.iterator : Symbol(SymbolConstructor.iterator, Decl(lib.es2015.iterable.d.ts, --, --))
|
||||
>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2019.symbol.d.ts, --, --))
|
||||
>iterator : Symbol(SymbolConstructor.iterator, Decl(lib.es2015.iterable.d.ts, --, --))
|
||||
>strings : Symbol(strings, Decl(spreadIndexSignature.ts, 0, 13))
|
||||
|
||||
const o3 = { [Symbol.iterator]: 1, ...symbols };
|
||||
>o3 : Symbol(o3, Decl(spreadIndexSignature.ts, 5, 5))
|
||||
>[Symbol.iterator] : Symbol([Symbol.iterator], Decl(spreadIndexSignature.ts, 5, 12))
|
||||
>Symbol.iterator : Symbol(SymbolConstructor.iterator, Decl(lib.es2015.iterable.d.ts, --, --))
|
||||
>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2019.symbol.d.ts, --, --))
|
||||
>iterator : Symbol(SymbolConstructor.iterator, Decl(lib.es2015.iterable.d.ts, --, --))
|
||||
>symbols : Symbol(symbols, Decl(spreadIndexSignature.ts, 1, 13))
|
||||
|
||||
36
tests/baselines/reference/spreadIndexSignature.types
Normal file
36
tests/baselines/reference/spreadIndexSignature.types
Normal file
@ -0,0 +1,36 @@
|
||||
//// [tests/cases/compiler/spreadIndexSignature.ts] ////
|
||||
|
||||
=== spreadIndexSignature.ts ===
|
||||
declare const strings: Record<string, string>;
|
||||
>strings : Record<string, string>
|
||||
|
||||
declare const symbols: Record<symbol, string>;
|
||||
>symbols : Record<symbol, string>
|
||||
|
||||
const o1 = { a: 1, ...strings };
|
||||
>o1 : { [x: string]: string | number; a: number; }
|
||||
>{ a: 1, ...strings } : { [x: string]: string | number; a: number; }
|
||||
>a : number
|
||||
>1 : 1
|
||||
>strings : Record<string, string>
|
||||
|
||||
const o2 = { [Symbol.iterator]: 1, ...strings };
|
||||
>o2 : { [x: string]: string; [Symbol.iterator]: number; }
|
||||
>{ [Symbol.iterator]: 1, ...strings } : { [x: string]: string; [Symbol.iterator]: number; }
|
||||
>[Symbol.iterator] : number
|
||||
>Symbol.iterator : unique symbol
|
||||
>Symbol : SymbolConstructor
|
||||
>iterator : unique symbol
|
||||
>1 : 1
|
||||
>strings : Record<string, string>
|
||||
|
||||
const o3 = { [Symbol.iterator]: 1, ...symbols };
|
||||
>o3 : { [x: symbol]: string | number; [Symbol.iterator]: number; }
|
||||
>{ [Symbol.iterator]: 1, ...symbols } : { [x: symbol]: string | number; [Symbol.iterator]: number; }
|
||||
>[Symbol.iterator] : number
|
||||
>Symbol.iterator : unique symbol
|
||||
>Symbol : SymbolConstructor
|
||||
>iterator : unique symbol
|
||||
>1 : 1
|
||||
>symbols : Record<symbol, string>
|
||||
|
||||
8
tests/cases/compiler/spreadIndexSignature.ts
Normal file
8
tests/cases/compiler/spreadIndexSignature.ts
Normal file
@ -0,0 +1,8 @@
|
||||
// @target: esnext
|
||||
|
||||
declare const strings: Record<string, string>;
|
||||
declare const symbols: Record<symbol, string>;
|
||||
|
||||
const o1 = { a: 1, ...strings };
|
||||
const o2 = { [Symbol.iterator]: 1, ...strings };
|
||||
const o3 = { [Symbol.iterator]: 1, ...symbols };
|
||||
Loading…
x
Reference in New Issue
Block a user