Add numeric constraint to type parameter of mapped types with name type and array constraints (#55774)

This commit is contained in:
Mateusz Burzyński 2024-01-16 19:59:00 +01:00 committed by GitHub
parent bbef6a7a31
commit 3f8707d04f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
17 changed files with 437 additions and 224 deletions

View File

@ -13850,6 +13850,14 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
}
function forEachMappedTypePropertyKeyTypeAndIndexSignatureKeyType(type: Type, include: TypeFlags, stringsOnly: boolean, cb: (keyType: Type) => void) {
if (isTupleType(type)) {
forEachType(getUnionType(getElementTypes(type).map((_, i) => getStringLiteralType("" + i))), cb);
return;
}
if (isArrayType(type)) {
cb(numberType);
return;
}
for (const prop of getPropertiesOfType(type)) {
cb(getLiteralTypeFromProperty(prop, include));
}
@ -16242,8 +16250,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
}
}
// Given a homomorphic mapped type { [K in keyof T]: XXX }, where T is constrained to an array or tuple type, in the
// template type XXX, K has an added constraint of number | `${number}`.
else if (type.flags & TypeFlags.TypeParameter && parent.kind === SyntaxKind.MappedType && node === (parent as MappedTypeNode).type) {
// template type XXX, K has an added constraint of number | `${number}`. The same is added in the optional name type.
else if (type.flags & TypeFlags.TypeParameter && parent.kind === SyntaxKind.MappedType && (node === (parent as MappedTypeNode).type || node === (parent as MappedTypeNode).nameType)) {
const mappedType = getTypeFromTypeNode(parent as TypeNode) as MappedType;
if (getTypeParameterFromMappedType(mappedType) === getActualTypeVariable(type)) {
const typeParameter = getHomomorphicTypeVariable(mappedType);

View File

@ -0,0 +1,36 @@
//// [tests/cases/compiler/mappedTypeHomomorphicTupleInstantiationNameTypeKeys.ts] ////
=== mappedTypeHomomorphicTupleInstantiationNameTypeKeys.ts ===
// https://github.com/microsoft/TypeScript/pull/55774#issuecomment-1813484949
type Mapper<T> = {
>Mapper : Symbol(Mapper, Decl(mappedTypeHomomorphicTupleInstantiationNameTypeKeys.ts, 0, 0))
>T : Symbol(T, Decl(mappedTypeHomomorphicTupleInstantiationNameTypeKeys.ts, 2, 12))
[K in keyof T as K]: T[K] extends NonNullable<T[K]> ? T[K] : never;
>K : Symbol(K, Decl(mappedTypeHomomorphicTupleInstantiationNameTypeKeys.ts, 3, 3))
>T : Symbol(T, Decl(mappedTypeHomomorphicTupleInstantiationNameTypeKeys.ts, 2, 12))
>K : Symbol(K, Decl(mappedTypeHomomorphicTupleInstantiationNameTypeKeys.ts, 3, 3))
>T : Symbol(T, Decl(mappedTypeHomomorphicTupleInstantiationNameTypeKeys.ts, 2, 12))
>K : Symbol(K, Decl(mappedTypeHomomorphicTupleInstantiationNameTypeKeys.ts, 3, 3))
>NonNullable : Symbol(NonNullable, Decl(lib.es5.d.ts, --, --))
>T : Symbol(T, Decl(mappedTypeHomomorphicTupleInstantiationNameTypeKeys.ts, 2, 12))
>K : Symbol(K, Decl(mappedTypeHomomorphicTupleInstantiationNameTypeKeys.ts, 3, 3))
>T : Symbol(T, Decl(mappedTypeHomomorphicTupleInstantiationNameTypeKeys.ts, 2, 12))
>K : Symbol(K, Decl(mappedTypeHomomorphicTupleInstantiationNameTypeKeys.ts, 3, 3))
};
type Mapped = Mapper<[1, 2]>;
>Mapped : Symbol(Mapped, Decl(mappedTypeHomomorphicTupleInstantiationNameTypeKeys.ts, 4, 2))
>Mapper : Symbol(Mapper, Decl(mappedTypeHomomorphicTupleInstantiationNameTypeKeys.ts, 0, 0))
type Keys = keyof Mapper<[1, 2]>;
>Keys : Symbol(Keys, Decl(mappedTypeHomomorphicTupleInstantiationNameTypeKeys.ts, 6, 29))
>Mapper : Symbol(Mapper, Decl(mappedTypeHomomorphicTupleInstantiationNameTypeKeys.ts, 0, 0))
type SomeType = Mapped[Keys]; // ok
>SomeType : Symbol(SomeType, Decl(mappedTypeHomomorphicTupleInstantiationNameTypeKeys.ts, 7, 33))
>Mapped : Symbol(Mapped, Decl(mappedTypeHomomorphicTupleInstantiationNameTypeKeys.ts, 4, 2))
>Keys : Symbol(Keys, Decl(mappedTypeHomomorphicTupleInstantiationNameTypeKeys.ts, 6, 29))

View File

@ -0,0 +1,20 @@
//// [tests/cases/compiler/mappedTypeHomomorphicTupleInstantiationNameTypeKeys.ts] ////
=== mappedTypeHomomorphicTupleInstantiationNameTypeKeys.ts ===
// https://github.com/microsoft/TypeScript/pull/55774#issuecomment-1813484949
type Mapper<T> = {
>Mapper : Mapper<T>
[K in keyof T as K]: T[K] extends NonNullable<T[K]> ? T[K] : never;
};
type Mapped = Mapper<[1, 2]>;
>Mapped : Mapper<[1, 2]>
type Keys = keyof Mapper<[1, 2]>;
>Keys : "0" | "1"
type SomeType = Mapped[Keys]; // ok
>SomeType : 2 | 1

View File

@ -0,0 +1,149 @@
//// [tests/cases/compiler/mappedTypeTupleConstraintTypeParameterInNameType.ts] ////
=== mappedTypeTupleConstraintTypeParameterInNameType.ts ===
// based on https://github.com/microsoft/TypeScript/issues/55762
declare class Decoder<T> {
>Decoder : Symbol(Decoder, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 0, 0))
>T : Symbol(T, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 2, 22))
decode(arrayBuffer: ArrayBuffer): T;
>decode : Symbol(Decoder.decode, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 2, 26))
>arrayBuffer : Symbol(arrayBuffer, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 3, 9))
>ArrayBuffer : Symbol(ArrayBuffer, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
>T : Symbol(T, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 2, 22))
}
type ValueTypeOf<T extends Decoder<any>> = T extends Decoder<infer R>
>ValueTypeOf : Symbol(ValueTypeOf, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 4, 1))
>T : Symbol(T, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 6, 17))
>Decoder : Symbol(Decoder, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 0, 0))
>T : Symbol(T, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 6, 17))
>Decoder : Symbol(Decoder, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 0, 0))
>R : Symbol(R, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 6, 66))
? R
>R : Symbol(R, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 6, 66))
: never;
type StructDescriptor = ReadonlyArray<
>StructDescriptor : Symbol(StructDescriptor, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 8, 10))
>ReadonlyArray : Symbol(ReadonlyArray, Decl(lib.es5.d.ts, --, --))
readonly [key: string, type: Decoder<any>]
>Decoder : Symbol(Decoder, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 0, 0))
>;
type StructTypeFor<Descriptor extends StructDescriptor> = {
>StructTypeFor : Symbol(StructTypeFor, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 12, 2))
>Descriptor : Symbol(Descriptor, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 14, 19))
>StructDescriptor : Symbol(StructDescriptor, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 8, 10))
[K in keyof Descriptor as Descriptor[K][0]]: ValueTypeOf<Descriptor[K][1]>;
>K : Symbol(K, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 15, 3))
>Descriptor : Symbol(Descriptor, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 14, 19))
>Descriptor : Symbol(Descriptor, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 14, 19))
>K : Symbol(K, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 15, 3))
>ValueTypeOf : Symbol(ValueTypeOf, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 4, 1))
>Descriptor : Symbol(Descriptor, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 14, 19))
>K : Symbol(K, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 15, 3))
};
class StructDecoder<const Descriptor extends StructDescriptor> extends Decoder<
>StructDecoder : Symbol(StructDecoder, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 16, 2))
>Descriptor : Symbol(Descriptor, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 18, 20))
>StructDescriptor : Symbol(StructDescriptor, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 8, 10))
>Decoder : Symbol(Decoder, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 0, 0))
StructTypeFor<Descriptor>
>StructTypeFor : Symbol(StructTypeFor, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 12, 2))
>Descriptor : Symbol(Descriptor, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 18, 20))
> {
constructor(descriptor: Descriptor) {
>descriptor : Symbol(descriptor, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 21, 14))
>Descriptor : Symbol(Descriptor, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 18, 20))
super();
>super : Symbol(Decoder, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 0, 0))
}
}
declare const i32Decoder: Decoder<number>;
>i32Decoder : Symbol(i32Decoder, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 26, 13))
>Decoder : Symbol(Decoder, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 0, 0))
declare const i64Decoder: Decoder<bigint>;
>i64Decoder : Symbol(i64Decoder, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 27, 13))
>Decoder : Symbol(Decoder, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 0, 0))
const structDecoder1 = new StructDecoder([
>structDecoder1 : Symbol(structDecoder1, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 29, 5))
>StructDecoder : Symbol(StructDecoder, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 16, 2))
["a", i32Decoder],
>i32Decoder : Symbol(i32Decoder, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 26, 13))
["b", i64Decoder],
>i64Decoder : Symbol(i64Decoder, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 27, 13))
]);
const struct1 = structDecoder1.decode(new ArrayBuffer(100));
>struct1 : Symbol(struct1, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 34, 5))
>structDecoder1.decode : Symbol(Decoder.decode, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 2, 26))
>structDecoder1 : Symbol(structDecoder1, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 29, 5))
>decode : Symbol(Decoder.decode, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 2, 26))
>ArrayBuffer : Symbol(ArrayBuffer, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
const v1_1: number = struct1.a;
>v1_1 : Symbol(v1_1, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 36, 5))
>struct1.a : Symbol(a)
>struct1 : Symbol(struct1, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 34, 5))
>a : Symbol(a)
const v1_2: bigint = struct1.b;
>v1_2 : Symbol(v1_2, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 37, 5))
>struct1.b : Symbol(b)
>struct1 : Symbol(struct1, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 34, 5))
>b : Symbol(b)
declare const descriptor2: [["a", Decoder<number>], ["b", Decoder<string>], ...["c", Decoder<bigint>][]]
>descriptor2 : Symbol(descriptor2, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 39, 13))
>Decoder : Symbol(Decoder, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 0, 0))
>Decoder : Symbol(Decoder, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 0, 0))
>Decoder : Symbol(Decoder, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 0, 0))
const structDecoder2 = new StructDecoder(descriptor2);
>structDecoder2 : Symbol(structDecoder2, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 40, 5))
>StructDecoder : Symbol(StructDecoder, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 16, 2))
>descriptor2 : Symbol(descriptor2, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 39, 13))
const struct2 = structDecoder2.decode(new ArrayBuffer(100));
>struct2 : Symbol(struct2, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 42, 5))
>structDecoder2.decode : Symbol(Decoder.decode, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 2, 26))
>structDecoder2 : Symbol(structDecoder2, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 40, 5))
>decode : Symbol(Decoder.decode, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 2, 26))
>ArrayBuffer : Symbol(ArrayBuffer, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
const v2_1: number = struct2.a;
>v2_1 : Symbol(v2_1, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 44, 5))
>struct2.a : Symbol(a)
>struct2 : Symbol(struct2, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 42, 5))
>a : Symbol(a)
const v2_2: string = struct2.b;
>v2_2 : Symbol(v2_2, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 45, 5))
>struct2.b : Symbol(b)
>struct2 : Symbol(struct2, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 42, 5))
>b : Symbol(b)
const v2_3: bigint = struct2.c;
>v2_3 : Symbol(v2_3, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 46, 5))
>struct2.c : Symbol(c)
>struct2 : Symbol(struct2, Decl(mappedTypeTupleConstraintTypeParameterInNameType.ts, 42, 5))
>c : Symbol(c)

View File

@ -0,0 +1,129 @@
//// [tests/cases/compiler/mappedTypeTupleConstraintTypeParameterInNameType.ts] ////
=== mappedTypeTupleConstraintTypeParameterInNameType.ts ===
// based on https://github.com/microsoft/TypeScript/issues/55762
declare class Decoder<T> {
>Decoder : Decoder<T>
decode(arrayBuffer: ArrayBuffer): T;
>decode : (arrayBuffer: ArrayBuffer) => T
>arrayBuffer : ArrayBuffer
}
type ValueTypeOf<T extends Decoder<any>> = T extends Decoder<infer R>
>ValueTypeOf : ValueTypeOf<T>
? R
: never;
type StructDescriptor = ReadonlyArray<
>StructDescriptor : readonly (readonly [key: string, type: Decoder<any>])[]
readonly [key: string, type: Decoder<any>]
>;
type StructTypeFor<Descriptor extends StructDescriptor> = {
>StructTypeFor : StructTypeFor<Descriptor>
[K in keyof Descriptor as Descriptor[K][0]]: ValueTypeOf<Descriptor[K][1]>;
};
class StructDecoder<const Descriptor extends StructDescriptor> extends Decoder<
>StructDecoder : StructDecoder<Descriptor>
>Decoder : Decoder<StructTypeFor<Descriptor>>
StructTypeFor<Descriptor>
> {
constructor(descriptor: Descriptor) {
>descriptor : Descriptor
super();
>super() : void
>super : typeof Decoder
}
}
declare const i32Decoder: Decoder<number>;
>i32Decoder : Decoder<number>
declare const i64Decoder: Decoder<bigint>;
>i64Decoder : Decoder<bigint>
const structDecoder1 = new StructDecoder([
>structDecoder1 : StructDecoder<readonly [readonly ["a", Decoder<number>], readonly ["b", Decoder<bigint>]]>
>new StructDecoder([ ["a", i32Decoder], ["b", i64Decoder],]) : StructDecoder<readonly [readonly ["a", Decoder<number>], readonly ["b", Decoder<bigint>]]>
>StructDecoder : typeof StructDecoder
>[ ["a", i32Decoder], ["b", i64Decoder],] : [["a", Decoder<number>], ["b", Decoder<bigint>]]
["a", i32Decoder],
>["a", i32Decoder] : ["a", Decoder<number>]
>"a" : "a"
>i32Decoder : Decoder<number>
["b", i64Decoder],
>["b", i64Decoder] : ["b", Decoder<bigint>]
>"b" : "b"
>i64Decoder : Decoder<bigint>
]);
const struct1 = structDecoder1.decode(new ArrayBuffer(100));
>struct1 : StructTypeFor<readonly [readonly ["a", Decoder<number>], readonly ["b", Decoder<bigint>]]>
>structDecoder1.decode(new ArrayBuffer(100)) : StructTypeFor<readonly [readonly ["a", Decoder<number>], readonly ["b", Decoder<bigint>]]>
>structDecoder1.decode : (arrayBuffer: ArrayBuffer) => StructTypeFor<readonly [readonly ["a", Decoder<number>], readonly ["b", Decoder<bigint>]]>
>structDecoder1 : StructDecoder<readonly [readonly ["a", Decoder<number>], readonly ["b", Decoder<bigint>]]>
>decode : (arrayBuffer: ArrayBuffer) => StructTypeFor<readonly [readonly ["a", Decoder<number>], readonly ["b", Decoder<bigint>]]>
>new ArrayBuffer(100) : ArrayBuffer
>ArrayBuffer : ArrayBufferConstructor
>100 : 100
const v1_1: number = struct1.a;
>v1_1 : number
>struct1.a : number
>struct1 : StructTypeFor<readonly [readonly ["a", Decoder<number>], readonly ["b", Decoder<bigint>]]>
>a : number
const v1_2: bigint = struct1.b;
>v1_2 : bigint
>struct1.b : bigint
>struct1 : StructTypeFor<readonly [readonly ["a", Decoder<number>], readonly ["b", Decoder<bigint>]]>
>b : bigint
declare const descriptor2: [["a", Decoder<number>], ["b", Decoder<string>], ...["c", Decoder<bigint>][]]
>descriptor2 : [["a", Decoder<number>], ["b", Decoder<string>], ...["c", Decoder<bigint>][]]
const structDecoder2 = new StructDecoder(descriptor2);
>structDecoder2 : StructDecoder<[["a", Decoder<number>], ["b", Decoder<string>], ...["c", Decoder<bigint>][]]>
>new StructDecoder(descriptor2) : StructDecoder<[["a", Decoder<number>], ["b", Decoder<string>], ...["c", Decoder<bigint>][]]>
>StructDecoder : typeof StructDecoder
>descriptor2 : [["a", Decoder<number>], ["b", Decoder<string>], ...["c", Decoder<bigint>][]]
const struct2 = structDecoder2.decode(new ArrayBuffer(100));
>struct2 : StructTypeFor<[["a", Decoder<number>], ["b", Decoder<string>], ...["c", Decoder<bigint>][]]>
>structDecoder2.decode(new ArrayBuffer(100)) : StructTypeFor<[["a", Decoder<number>], ["b", Decoder<string>], ...["c", Decoder<bigint>][]]>
>structDecoder2.decode : (arrayBuffer: ArrayBuffer) => StructTypeFor<[["a", Decoder<number>], ["b", Decoder<string>], ...["c", Decoder<bigint>][]]>
>structDecoder2 : StructDecoder<[["a", Decoder<number>], ["b", Decoder<string>], ...["c", Decoder<bigint>][]]>
>decode : (arrayBuffer: ArrayBuffer) => StructTypeFor<[["a", Decoder<number>], ["b", Decoder<string>], ...["c", Decoder<bigint>][]]>
>new ArrayBuffer(100) : ArrayBuffer
>ArrayBuffer : ArrayBufferConstructor
>100 : 100
const v2_1: number = struct2.a;
>v2_1 : number
>struct2.a : number
>struct2 : StructTypeFor<[["a", Decoder<number>], ["b", Decoder<string>], ...["c", Decoder<bigint>][]]>
>a : number
const v2_2: string = struct2.b;
>v2_2 : string
>struct2.b : string
>struct2 : StructTypeFor<[["a", Decoder<number>], ["b", Decoder<string>], ...["c", Decoder<bigint>][]]>
>b : string
const v2_3: bigint = struct2.c;
>v2_3 : bigint
>struct2.c : bigint
>struct2 : StructTypeFor<[["a", Decoder<number>], ["b", Decoder<string>], ...["c", Decoder<bigint>][]]>
>c : bigint

View File

@ -1,11 +1,11 @@
mappedTypeWithAsClauseAndLateBoundProperty.ts(3,1): error TS2741: Property 'length' is missing in type '{ [x: number]: number; toString: () => string; toLocaleString: () => string; pop: () => number; push: (...items: number[]) => number; concat: { (...items: ConcatArray<number>[]): number[]; (...items: (number | ConcatArray<number>)[]): number[]; }; join: (separator?: string) => string; reverse: () => number[]; shift: () => number; slice: (start?: number, end?: number) => number[]; sort: (compareFn?: (a: number, b: number) => number) => number[]; splice: { (start: number, deleteCount?: number): number[]; (start: number, deleteCount: number, ...items: number[]): number[]; }; unshift: (...items: number[]) => number; indexOf: (searchElement: number, fromIndex?: number) => number; lastIndexOf: (searchElement: number, fromIndex?: number) => number; every: { <S extends number>(predicate: (value: number, index: number, array: number[]) => value is S, thisArg?: any): this is S[]; (predicate: (value: number, index: number, array: number[]) => unknown, thisArg?: any): boolean; }; some: (predicate: (value: number, index: number, array: number[]) => unknown, thisArg?: any) => boolean; forEach: (callbackfn: (value: number, index: number, array: number[]) => void, thisArg?: any) => void; map: <U>(callbackfn: (value: number, index: number, array: number[]) => U, thisArg?: any) => U[]; filter: { <S extends number>(predicate: (value: number, index: number, array: number[]) => value is S, thisArg?: any): S[]; (predicate: (value: number, index: number, array: number[]) => unknown, thisArg?: any): number[]; }; reduce: { (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number): number; (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number, initialValue: number): number; <U>(callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: number[]) => U, initialValue: U): U; }; reduceRight: { (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number): number; (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number, initialValue: number): number; <U>(callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: number[]) => U, initialValue: U): U; }; find: { <S extends number>(predicate: (value: number, index: number, obj: number[]) => value is S, thisArg?: any): S; (predicate: (value: number, index: number, obj: number[]) => unknown, thisArg?: any): number; }; findIndex: (predicate: (value: number, index: number, obj: number[]) => unknown, thisArg?: any) => number; fill: (value: number, start?: number, end?: number) => number[]; copyWithin: (target: number, start: number, end?: number) => number[]; entries: () => IterableIterator<[number, number]>; keys: () => IterableIterator<number>; values: () => IterableIterator<number>; includes: (searchElement: number, fromIndex?: number) => boolean; flatMap: <U, This = undefined>(callback: (this: This, value: number, index: number, array: number[]) => U | readonly U[], thisArg?: This) => U[]; flat: <A, D extends number = 1>(this: A, depth?: D) => FlatArray<A, D>[]; [Symbol.iterator]: () => IterableIterator<number>; readonly [Symbol.unscopables]: { [x: number]: boolean; length?: boolean; toString?: boolean; toLocaleString?: boolean; pop?: boolean; push?: boolean; concat?: boolean; join?: boolean; reverse?: boolean; shift?: boolean; slice?: boolean; sort?: boolean; splice?: boolean; unshift?: boolean; indexOf?: boolean; lastIndexOf?: boolean; every?: boolean; some?: boolean; forEach?: boolean; map?: boolean; filter?: boolean; reduce?: boolean; reduceRight?: boolean; find?: boolean; findIndex?: boolean; fill?: boolean; copyWithin?: boolean; entries?: boolean; keys?: boolean; values?: boolean; includes?: boolean; flatMap?: boolean; flat?: boolean; [Symbol.iterator]?: boolean; readonly [Symbol.unscopables]?: boolean; }; }' but required in type 'number[]'.
mappedTypeWithAsClauseAndLateBoundProperty.ts(3,1): error TS2741: Property 'length' is missing in type '{ [x: number]: number; [iterator]: () => IterableIterator<number>; [unscopables]: { [x: number]: boolean; }; toString: () => string; toLocaleString: () => string; pop: () => number; push: (...items: number[]) => number; concat: { (...items: ConcatArray<number>[]): number[]; (...items: (number | ConcatArray<number>)[]): number[]; }; join: (separator?: string) => string; reverse: () => number[]; shift: () => number; slice: (start?: number, end?: number) => number[]; sort: (compareFn?: (a: number, b: number) => number) => number[]; splice: { (start: number, deleteCount?: number): number[]; (start: number, deleteCount: number, ...items: number[]): number[]; }; unshift: (...items: number[]) => number; indexOf: (searchElement: number, fromIndex?: number) => number; lastIndexOf: (searchElement: number, fromIndex?: number) => number; every: { <S extends number>(predicate: (value: number, index: number, array: number[]) => value is S, thisArg?: any): this is S[]; (predicate: (value: number, index: number, array: number[]) => unknown, thisArg?: any): boolean; }; some: (predicate: (value: number, index: number, array: number[]) => unknown, thisArg?: any) => boolean; forEach: (callbackfn: (value: number, index: number, array: number[]) => void, thisArg?: any) => void; map: <U>(callbackfn: (value: number, index: number, array: number[]) => U, thisArg?: any) => U[]; filter: { <S extends number>(predicate: (value: number, index: number, array: number[]) => value is S, thisArg?: any): S[]; (predicate: (value: number, index: number, array: number[]) => unknown, thisArg?: any): number[]; }; reduce: { (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number): number; (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number, initialValue: number): number; <U>(callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: number[]) => U, initialValue: U): U; }; reduceRight: { (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number): number; (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number, initialValue: number): number; <U>(callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: number[]) => U, initialValue: U): U; }; find: { <S extends number>(predicate: (value: number, index: number, obj: number[]) => value is S, thisArg?: any): S; (predicate: (value: number, index: number, obj: number[]) => unknown, thisArg?: any): number; }; findIndex: (predicate: (value: number, index: number, obj: number[]) => unknown, thisArg?: any) => number; fill: (value: number, start?: number, end?: number) => number[]; copyWithin: (target: number, start: number, end?: number) => number[]; entries: () => IterableIterator<[number, number]>; keys: () => IterableIterator<number>; values: () => IterableIterator<number>; includes: (searchElement: number, fromIndex?: number) => boolean; flatMap: <U, This = undefined>(callback: (this: This, value: number, index: number, array: number[]) => U | readonly U[], thisArg?: This) => U[]; flat: <A, D extends number = 1>(this: A, depth?: D) => FlatArray<A, D>[]; }' but required in type 'number[]'.
==== mappedTypeWithAsClauseAndLateBoundProperty.ts (1 errors) ====
declare let tgt2: number[];
declare let src2: { [K in keyof number[] as Exclude<K, "length">]: (number[])[K] };
declare let src2: { [K in keyof number[] & PropertyKey as Exclude<K, "length">]: (number[])[K] };
tgt2 = src2; // Should error
~~~~
!!! error TS2741: Property 'length' is missing in type '{ [x: number]: number; toString: () => string; toLocaleString: () => string; pop: () => number; push: (...items: number[]) => number; concat: { (...items: ConcatArray<number>[]): number[]; (...items: (number | ConcatArray<number>)[]): number[]; }; join: (separator?: string) => string; reverse: () => number[]; shift: () => number; slice: (start?: number, end?: number) => number[]; sort: (compareFn?: (a: number, b: number) => number) => number[]; splice: { (start: number, deleteCount?: number): number[]; (start: number, deleteCount: number, ...items: number[]): number[]; }; unshift: (...items: number[]) => number; indexOf: (searchElement: number, fromIndex?: number) => number; lastIndexOf: (searchElement: number, fromIndex?: number) => number; every: { <S extends number>(predicate: (value: number, index: number, array: number[]) => value is S, thisArg?: any): this is S[]; (predicate: (value: number, index: number, array: number[]) => unknown, thisArg?: any): boolean; }; some: (predicate: (value: number, index: number, array: number[]) => unknown, thisArg?: any) => boolean; forEach: (callbackfn: (value: number, index: number, array: number[]) => void, thisArg?: any) => void; map: <U>(callbackfn: (value: number, index: number, array: number[]) => U, thisArg?: any) => U[]; filter: { <S extends number>(predicate: (value: number, index: number, array: number[]) => value is S, thisArg?: any): S[]; (predicate: (value: number, index: number, array: number[]) => unknown, thisArg?: any): number[]; }; reduce: { (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number): number; (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number, initialValue: number): number; <U>(callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: number[]) => U, initialValue: U): U; }; reduceRight: { (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number): number; (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number, initialValue: number): number; <U>(callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: number[]) => U, initialValue: U): U; }; find: { <S extends number>(predicate: (value: number, index: number, obj: number[]) => value is S, thisArg?: any): S; (predicate: (value: number, index: number, obj: number[]) => unknown, thisArg?: any): number; }; findIndex: (predicate: (value: number, index: number, obj: number[]) => unknown, thisArg?: any) => number; fill: (value: number, start?: number, end?: number) => number[]; copyWithin: (target: number, start: number, end?: number) => number[]; entries: () => IterableIterator<[number, number]>; keys: () => IterableIterator<number>; values: () => IterableIterator<number>; includes: (searchElement: number, fromIndex?: number) => boolean; flatMap: <U, This = undefined>(callback: (this: This, value: number, index: number, array: number[]) => U | readonly U[], thisArg?: This) => U[]; flat: <A, D extends number = 1>(this: A, depth?: D) => FlatArray<A, D>[]; [Symbol.iterator]: () => IterableIterator<number>; readonly [Symbol.unscopables]: { [x: number]: boolean; length?: boolean; toString?: boolean; toLocaleString?: boolean; pop?: boolean; push?: boolean; concat?: boolean; join?: boolean; reverse?: boolean; shift?: boolean; slice?: boolean; sort?: boolean; splice?: boolean; unshift?: boolean; indexOf?: boolean; lastIndexOf?: boolean; every?: boolean; some?: boolean; forEach?: boolean; map?: boolean; filter?: boolean; reduce?: boolean; reduceRight?: boolean; find?: boolean; findIndex?: boolean; fill?: boolean; copyWithin?: boolean; entries?: boolean; keys?: boolean; values?: boolean; includes?: boolean; flatMap?: boolean; flat?: boolean; [Symbol.iterator]?: boolean; readonly [Symbol.unscopables]?: boolean; }; }' but required in type 'number[]'.
!!! error TS2741: Property 'length' is missing in type '{ [x: number]: number; [iterator]: () => IterableIterator<number>; [unscopables]: { [x: number]: boolean; }; toString: () => string; toLocaleString: () => string; pop: () => number; push: (...items: number[]) => number; concat: { (...items: ConcatArray<number>[]): number[]; (...items: (number | ConcatArray<number>)[]): number[]; }; join: (separator?: string) => string; reverse: () => number[]; shift: () => number; slice: (start?: number, end?: number) => number[]; sort: (compareFn?: (a: number, b: number) => number) => number[]; splice: { (start: number, deleteCount?: number): number[]; (start: number, deleteCount: number, ...items: number[]): number[]; }; unshift: (...items: number[]) => number; indexOf: (searchElement: number, fromIndex?: number) => number; lastIndexOf: (searchElement: number, fromIndex?: number) => number; every: { <S extends number>(predicate: (value: number, index: number, array: number[]) => value is S, thisArg?: any): this is S[]; (predicate: (value: number, index: number, array: number[]) => unknown, thisArg?: any): boolean; }; some: (predicate: (value: number, index: number, array: number[]) => unknown, thisArg?: any) => boolean; forEach: (callbackfn: (value: number, index: number, array: number[]) => void, thisArg?: any) => void; map: <U>(callbackfn: (value: number, index: number, array: number[]) => U, thisArg?: any) => U[]; filter: { <S extends number>(predicate: (value: number, index: number, array: number[]) => value is S, thisArg?: any): S[]; (predicate: (value: number, index: number, array: number[]) => unknown, thisArg?: any): number[]; }; reduce: { (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number): number; (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number, initialValue: number): number; <U>(callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: number[]) => U, initialValue: U): U; }; reduceRight: { (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number): number; (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number, initialValue: number): number; <U>(callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: number[]) => U, initialValue: U): U; }; find: { <S extends number>(predicate: (value: number, index: number, obj: number[]) => value is S, thisArg?: any): S; (predicate: (value: number, index: number, obj: number[]) => unknown, thisArg?: any): number; }; findIndex: (predicate: (value: number, index: number, obj: number[]) => unknown, thisArg?: any) => number; fill: (value: number, start?: number, end?: number) => number[]; copyWithin: (target: number, start: number, end?: number) => number[]; entries: () => IterableIterator<[number, number]>; keys: () => IterableIterator<number>; values: () => IterableIterator<number>; includes: (searchElement: number, fromIndex?: number) => boolean; flatMap: <U, This = undefined>(callback: (this: This, value: number, index: number, array: number[]) => U | readonly U[], thisArg?: This) => U[]; flat: <A, D extends number = 1>(this: A, depth?: D) => FlatArray<A, D>[]; }' but required in type 'number[]'.
!!! related TS2728 lib.es5.d.ts:--:--: 'length' is declared here.

View File

@ -2,7 +2,7 @@
//// [mappedTypeWithAsClauseAndLateBoundProperty.ts]
declare let tgt2: number[];
declare let src2: { [K in keyof number[] as Exclude<K, "length">]: (number[])[K] };
declare let src2: { [K in keyof number[] & PropertyKey as Exclude<K, "length">]: (number[])[K] };
tgt2 = src2; // Should error

View File

@ -4,9 +4,10 @@
declare let tgt2: number[];
>tgt2 : Symbol(tgt2, Decl(mappedTypeWithAsClauseAndLateBoundProperty.ts, 0, 11))
declare let src2: { [K in keyof number[] as Exclude<K, "length">]: (number[])[K] };
declare let src2: { [K in keyof number[] & PropertyKey as Exclude<K, "length">]: (number[])[K] };
>src2 : Symbol(src2, Decl(mappedTypeWithAsClauseAndLateBoundProperty.ts, 1, 11))
>K : Symbol(K, Decl(mappedTypeWithAsClauseAndLateBoundProperty.ts, 1, 21))
>PropertyKey : Symbol(PropertyKey, Decl(lib.es5.d.ts, --, --))
>Exclude : Symbol(Exclude, Decl(lib.es5.d.ts, --, --))
>K : Symbol(K, Decl(mappedTypeWithAsClauseAndLateBoundProperty.ts, 1, 21))
>K : Symbol(K, Decl(mappedTypeWithAsClauseAndLateBoundProperty.ts, 1, 21))

View File

@ -4,11 +4,11 @@
declare let tgt2: number[];
>tgt2 : number[]
declare let src2: { [K in keyof number[] as Exclude<K, "length">]: (number[])[K] };
>src2 : { [x: number]: number; toString: () => string; toLocaleString: () => string; pop: () => number; push: (...items: number[]) => number; concat: { (...items: ConcatArray<number>[]): number[]; (...items: (number | ConcatArray<number>)[]): number[]; }; join: (separator?: string) => string; reverse: () => number[]; shift: () => number; slice: (start?: number, end?: number) => number[]; sort: (compareFn?: (a: number, b: number) => number) => number[]; splice: { (start: number, deleteCount?: number): number[]; (start: number, deleteCount: number, ...items: number[]): number[]; }; unshift: (...items: number[]) => number; indexOf: (searchElement: number, fromIndex?: number) => number; lastIndexOf: (searchElement: number, fromIndex?: number) => number; every: { <S extends number>(predicate: (value: number, index: number, array: number[]) => value is S, thisArg?: any): this is S[]; (predicate: (value: number, index: number, array: number[]) => unknown, thisArg?: any): boolean; }; some: (predicate: (value: number, index: number, array: number[]) => unknown, thisArg?: any) => boolean; forEach: (callbackfn: (value: number, index: number, array: number[]) => void, thisArg?: any) => void; map: <U>(callbackfn: (value: number, index: number, array: number[]) => U, thisArg?: any) => U[]; filter: { <S_1 extends number>(predicate: (value: number, index: number, array: number[]) => value is S_1, thisArg?: any): S_1[]; (predicate: (value: number, index: number, array: number[]) => unknown, thisArg?: any): number[]; }; reduce: { (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number): number; (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number, initialValue: number): number; <U_1>(callbackfn: (previousValue: U_1, currentValue: number, currentIndex: number, array: number[]) => U_1, initialValue: U_1): U_1; }; reduceRight: { (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number): number; (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number, initialValue: number): number; <U_2>(callbackfn: (previousValue: U_2, currentValue: number, currentIndex: number, array: number[]) => U_2, initialValue: U_2): U_2; }; find: { <S_2 extends number>(predicate: (value: number, index: number, obj: number[]) => value is S_2, thisArg?: any): S_2; (predicate: (value: number, index: number, obj: number[]) => unknown, thisArg?: any): number; }; findIndex: (predicate: (value: number, index: number, obj: number[]) => unknown, thisArg?: any) => number; fill: (value: number, start?: number, end?: number) => number[]; copyWithin: (target: number, start: number, end?: number) => number[]; entries: () => IterableIterator<[number, number]>; keys: () => IterableIterator<number>; values: () => IterableIterator<number>; includes: (searchElement: number, fromIndex?: number) => boolean; flatMap: <U_3, This = undefined>(callback: (this: This, value: number, index: number, array: number[]) => U_3 | readonly U_3[], thisArg?: This) => U_3[]; flat: <A, D extends number = 1>(this: A, depth?: D) => FlatArray<A, D>[]; [Symbol.iterator]: () => IterableIterator<number>; readonly [Symbol.unscopables]: { [x: number]: boolean; length?: boolean; toString?: boolean; toLocaleString?: boolean; pop?: boolean; push?: boolean; concat?: boolean; join?: boolean; reverse?: boolean; shift?: boolean; slice?: boolean; sort?: boolean; splice?: boolean; unshift?: boolean; indexOf?: boolean; lastIndexOf?: boolean; every?: boolean; some?: boolean; forEach?: boolean; map?: boolean; filter?: boolean; reduce?: boolean; reduceRight?: boolean; find?: boolean; findIndex?: boolean; fill?: boolean; copyWithin?: boolean; entries?: boolean; keys?: boolean; values?: boolean; includes?: boolean; flatMap?: boolean; flat?: boolean; [Symbol.iterator]?: boolean; readonly [Symbol.unscopables]?: boolean; }; }
declare let src2: { [K in keyof number[] & PropertyKey as Exclude<K, "length">]: (number[])[K] };
>src2 : { [x: number]: number; [Symbol.iterator]: () => IterableIterator<number>; [Symbol.unscopables]: { [x: number]: boolean; }; toString: () => string; toLocaleString: () => string; pop: () => number; push: (...items: number[]) => number; concat: { (...items: ConcatArray<number>[]): number[]; (...items: (number | ConcatArray<number>)[]): number[]; }; join: (separator?: string) => string; reverse: () => number[]; shift: () => number; slice: (start?: number, end?: number) => number[]; sort: (compareFn?: (a: number, b: number) => number) => number[]; splice: { (start: number, deleteCount?: number): number[]; (start: number, deleteCount: number, ...items: number[]): number[]; }; unshift: (...items: number[]) => number; indexOf: (searchElement: number, fromIndex?: number) => number; lastIndexOf: (searchElement: number, fromIndex?: number) => number; every: { <S extends number>(predicate: (value: number, index: number, array: number[]) => value is S, thisArg?: any): this is S[]; (predicate: (value: number, index: number, array: number[]) => unknown, thisArg?: any): boolean; }; some: (predicate: (value: number, index: number, array: number[]) => unknown, thisArg?: any) => boolean; forEach: (callbackfn: (value: number, index: number, array: number[]) => void, thisArg?: any) => void; map: <U>(callbackfn: (value: number, index: number, array: number[]) => U, thisArg?: any) => U[]; filter: { <S_1 extends number>(predicate: (value: number, index: number, array: number[]) => value is S_1, thisArg?: any): S_1[]; (predicate: (value: number, index: number, array: number[]) => unknown, thisArg?: any): number[]; }; reduce: { (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number): number; (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number, initialValue: number): number; <U_1>(callbackfn: (previousValue: U_1, currentValue: number, currentIndex: number, array: number[]) => U_1, initialValue: U_1): U_1; }; reduceRight: { (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number): number; (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number, initialValue: number): number; <U_2>(callbackfn: (previousValue: U_2, currentValue: number, currentIndex: number, array: number[]) => U_2, initialValue: U_2): U_2; }; find: { <S_2 extends number>(predicate: (value: number, index: number, obj: number[]) => value is S_2, thisArg?: any): S_2; (predicate: (value: number, index: number, obj: number[]) => unknown, thisArg?: any): number; }; findIndex: (predicate: (value: number, index: number, obj: number[]) => unknown, thisArg?: any) => number; fill: (value: number, start?: number, end?: number) => number[]; copyWithin: (target: number, start: number, end?: number) => number[]; entries: () => IterableIterator<[number, number]>; keys: () => IterableIterator<number>; values: () => IterableIterator<number>; includes: (searchElement: number, fromIndex?: number) => boolean; flatMap: <U_3, This = undefined>(callback: (this: This, value: number, index: number, array: number[]) => U_3 | readonly U_3[], thisArg?: This) => U_3[]; flat: <A, D extends number = 1>(this: A, depth?: D) => FlatArray<A, D>[]; }
tgt2 = src2; // Should error
>tgt2 = src2 : { [x: number]: number; toString: () => string; toLocaleString: () => string; pop: () => number; push: (...items: number[]) => number; concat: { (...items: ConcatArray<number>[]): number[]; (...items: (number | ConcatArray<number>)[]): number[]; }; join: (separator?: string) => string; reverse: () => number[]; shift: () => number; slice: (start?: number, end?: number) => number[]; sort: (compareFn?: (a: number, b: number) => number) => number[]; splice: { (start: number, deleteCount?: number): number[]; (start: number, deleteCount: number, ...items: number[]): number[]; }; unshift: (...items: number[]) => number; indexOf: (searchElement: number, fromIndex?: number) => number; lastIndexOf: (searchElement: number, fromIndex?: number) => number; every: { <S extends number>(predicate: (value: number, index: number, array: number[]) => value is S, thisArg?: any): this is S[]; (predicate: (value: number, index: number, array: number[]) => unknown, thisArg?: any): boolean; }; some: (predicate: (value: number, index: number, array: number[]) => unknown, thisArg?: any) => boolean; forEach: (callbackfn: (value: number, index: number, array: number[]) => void, thisArg?: any) => void; map: <U>(callbackfn: (value: number, index: number, array: number[]) => U, thisArg?: any) => U[]; filter: { <S_1 extends number>(predicate: (value: number, index: number, array: number[]) => value is S_1, thisArg?: any): S_1[]; (predicate: (value: number, index: number, array: number[]) => unknown, thisArg?: any): number[]; }; reduce: { (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number): number; (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number, initialValue: number): number; <U_1>(callbackfn: (previousValue: U_1, currentValue: number, currentIndex: number, array: number[]) => U_1, initialValue: U_1): U_1; }; reduceRight: { (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number): number; (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number, initialValue: number): number; <U_2>(callbackfn: (previousValue: U_2, currentValue: number, currentIndex: number, array: number[]) => U_2, initialValue: U_2): U_2; }; find: { <S_2 extends number>(predicate: (value: number, index: number, obj: number[]) => value is S_2, thisArg?: any): S_2; (predicate: (value: number, index: number, obj: number[]) => unknown, thisArg?: any): number; }; findIndex: (predicate: (value: number, index: number, obj: number[]) => unknown, thisArg?: any) => number; fill: (value: number, start?: number, end?: number) => number[]; copyWithin: (target: number, start: number, end?: number) => number[]; entries: () => IterableIterator<[number, number]>; keys: () => IterableIterator<number>; values: () => IterableIterator<number>; includes: (searchElement: number, fromIndex?: number) => boolean; flatMap: <U_3, This = undefined>(callback: (this: This, value: number, index: number, array: number[]) => U_3 | readonly U_3[], thisArg?: This) => U_3[]; flat: <A, D extends number = 1>(this: A, depth?: D) => FlatArray<A, D>[]; [Symbol.iterator]: () => IterableIterator<number>; readonly [Symbol.unscopables]: { [x: number]: boolean; length?: boolean; toString?: boolean; toLocaleString?: boolean; pop?: boolean; push?: boolean; concat?: boolean; join?: boolean; reverse?: boolean; shift?: boolean; slice?: boolean; sort?: boolean; splice?: boolean; unshift?: boolean; indexOf?: boolean; lastIndexOf?: boolean; every?: boolean; some?: boolean; forEach?: boolean; map?: boolean; filter?: boolean; reduce?: boolean; reduceRight?: boolean; find?: boolean; findIndex?: boolean; fill?: boolean; copyWithin?: boolean; entries?: boolean; keys?: boolean; values?: boolean; includes?: boolean; flatMap?: boolean; flat?: boolean; [Symbol.iterator]?: boolean; readonly [Symbol.unscopables]?: boolean; }; }
>tgt2 = src2 : { [x: number]: number; [Symbol.iterator]: () => IterableIterator<number>; [Symbol.unscopables]: { [x: number]: boolean; }; toString: () => string; toLocaleString: () => string; pop: () => number; push: (...items: number[]) => number; concat: { (...items: ConcatArray<number>[]): number[]; (...items: (number | ConcatArray<number>)[]): number[]; }; join: (separator?: string) => string; reverse: () => number[]; shift: () => number; slice: (start?: number, end?: number) => number[]; sort: (compareFn?: (a: number, b: number) => number) => number[]; splice: { (start: number, deleteCount?: number): number[]; (start: number, deleteCount: number, ...items: number[]): number[]; }; unshift: (...items: number[]) => number; indexOf: (searchElement: number, fromIndex?: number) => number; lastIndexOf: (searchElement: number, fromIndex?: number) => number; every: { <S extends number>(predicate: (value: number, index: number, array: number[]) => value is S, thisArg?: any): this is S[]; (predicate: (value: number, index: number, array: number[]) => unknown, thisArg?: any): boolean; }; some: (predicate: (value: number, index: number, array: number[]) => unknown, thisArg?: any) => boolean; forEach: (callbackfn: (value: number, index: number, array: number[]) => void, thisArg?: any) => void; map: <U>(callbackfn: (value: number, index: number, array: number[]) => U, thisArg?: any) => U[]; filter: { <S_1 extends number>(predicate: (value: number, index: number, array: number[]) => value is S_1, thisArg?: any): S_1[]; (predicate: (value: number, index: number, array: number[]) => unknown, thisArg?: any): number[]; }; reduce: { (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number): number; (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number, initialValue: number): number; <U_1>(callbackfn: (previousValue: U_1, currentValue: number, currentIndex: number, array: number[]) => U_1, initialValue: U_1): U_1; }; reduceRight: { (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number): number; (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number, initialValue: number): number; <U_2>(callbackfn: (previousValue: U_2, currentValue: number, currentIndex: number, array: number[]) => U_2, initialValue: U_2): U_2; }; find: { <S_2 extends number>(predicate: (value: number, index: number, obj: number[]) => value is S_2, thisArg?: any): S_2; (predicate: (value: number, index: number, obj: number[]) => unknown, thisArg?: any): number; }; findIndex: (predicate: (value: number, index: number, obj: number[]) => unknown, thisArg?: any) => number; fill: (value: number, start?: number, end?: number) => number[]; copyWithin: (target: number, start: number, end?: number) => number[]; entries: () => IterableIterator<[number, number]>; keys: () => IterableIterator<number>; values: () => IterableIterator<number>; includes: (searchElement: number, fromIndex?: number) => boolean; flatMap: <U_3, This = undefined>(callback: (this: This, value: number, index: number, array: number[]) => U_3 | readonly U_3[], thisArg?: This) => U_3[]; flat: <A, D extends number = 1>(this: A, depth?: D) => FlatArray<A, D>[]; }
>tgt2 : number[]
>src2 : { [x: number]: number; toString: () => string; toLocaleString: () => string; pop: () => number; push: (...items: number[]) => number; concat: { (...items: ConcatArray<number>[]): number[]; (...items: (number | ConcatArray<number>)[]): number[]; }; join: (separator?: string) => string; reverse: () => number[]; shift: () => number; slice: (start?: number, end?: number) => number[]; sort: (compareFn?: (a: number, b: number) => number) => number[]; splice: { (start: number, deleteCount?: number): number[]; (start: number, deleteCount: number, ...items: number[]): number[]; }; unshift: (...items: number[]) => number; indexOf: (searchElement: number, fromIndex?: number) => number; lastIndexOf: (searchElement: number, fromIndex?: number) => number; every: { <S extends number>(predicate: (value: number, index: number, array: number[]) => value is S, thisArg?: any): this is S[]; (predicate: (value: number, index: number, array: number[]) => unknown, thisArg?: any): boolean; }; some: (predicate: (value: number, index: number, array: number[]) => unknown, thisArg?: any) => boolean; forEach: (callbackfn: (value: number, index: number, array: number[]) => void, thisArg?: any) => void; map: <U>(callbackfn: (value: number, index: number, array: number[]) => U, thisArg?: any) => U[]; filter: { <S_1 extends number>(predicate: (value: number, index: number, array: number[]) => value is S_1, thisArg?: any): S_1[]; (predicate: (value: number, index: number, array: number[]) => unknown, thisArg?: any): number[]; }; reduce: { (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number): number; (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number, initialValue: number): number; <U_1>(callbackfn: (previousValue: U_1, currentValue: number, currentIndex: number, array: number[]) => U_1, initialValue: U_1): U_1; }; reduceRight: { (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number): number; (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number, initialValue: number): number; <U_2>(callbackfn: (previousValue: U_2, currentValue: number, currentIndex: number, array: number[]) => U_2, initialValue: U_2): U_2; }; find: { <S_2 extends number>(predicate: (value: number, index: number, obj: number[]) => value is S_2, thisArg?: any): S_2; (predicate: (value: number, index: number, obj: number[]) => unknown, thisArg?: any): number; }; findIndex: (predicate: (value: number, index: number, obj: number[]) => unknown, thisArg?: any) => number; fill: (value: number, start?: number, end?: number) => number[]; copyWithin: (target: number, start: number, end?: number) => number[]; entries: () => IterableIterator<[number, number]>; keys: () => IterableIterator<number>; values: () => IterableIterator<number>; includes: (searchElement: number, fromIndex?: number) => boolean; flatMap: <U_3, This = undefined>(callback: (this: This, value: number, index: number, array: number[]) => U_3 | readonly U_3[], thisArg?: This) => U_3[]; flat: <A, D extends number = 1>(this: A, depth?: D) => FlatArray<A, D>[]; [Symbol.iterator]: () => IterableIterator<number>; readonly [Symbol.unscopables]: { [x: number]: boolean; length?: boolean; toString?: boolean; toLocaleString?: boolean; pop?: boolean; push?: boolean; concat?: boolean; join?: boolean; reverse?: boolean; shift?: boolean; slice?: boolean; sort?: boolean; splice?: boolean; unshift?: boolean; indexOf?: boolean; lastIndexOf?: boolean; every?: boolean; some?: boolean; forEach?: boolean; map?: boolean; filter?: boolean; reduce?: boolean; reduceRight?: boolean; find?: boolean; findIndex?: boolean; fill?: boolean; copyWithin?: boolean; entries?: boolean; keys?: boolean; values?: boolean; includes?: boolean; flatMap?: boolean; flat?: boolean; [Symbol.iterator]?: boolean; readonly [Symbol.unscopables]?: boolean; }; }
>src2 : { [x: number]: number; [Symbol.iterator]: () => IterableIterator<number>; [Symbol.unscopables]: { [x: number]: boolean; }; toString: () => string; toLocaleString: () => string; pop: () => number; push: (...items: number[]) => number; concat: { (...items: ConcatArray<number>[]): number[]; (...items: (number | ConcatArray<number>)[]): number[]; }; join: (separator?: string) => string; reverse: () => number[]; shift: () => number; slice: (start?: number, end?: number) => number[]; sort: (compareFn?: (a: number, b: number) => number) => number[]; splice: { (start: number, deleteCount?: number): number[]; (start: number, deleteCount: number, ...items: number[]): number[]; }; unshift: (...items: number[]) => number; indexOf: (searchElement: number, fromIndex?: number) => number; lastIndexOf: (searchElement: number, fromIndex?: number) => number; every: { <S extends number>(predicate: (value: number, index: number, array: number[]) => value is S, thisArg?: any): this is S[]; (predicate: (value: number, index: number, array: number[]) => unknown, thisArg?: any): boolean; }; some: (predicate: (value: number, index: number, array: number[]) => unknown, thisArg?: any) => boolean; forEach: (callbackfn: (value: number, index: number, array: number[]) => void, thisArg?: any) => void; map: <U>(callbackfn: (value: number, index: number, array: number[]) => U, thisArg?: any) => U[]; filter: { <S_1 extends number>(predicate: (value: number, index: number, array: number[]) => value is S_1, thisArg?: any): S_1[]; (predicate: (value: number, index: number, array: number[]) => unknown, thisArg?: any): number[]; }; reduce: { (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number): number; (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number, initialValue: number): number; <U_1>(callbackfn: (previousValue: U_1, currentValue: number, currentIndex: number, array: number[]) => U_1, initialValue: U_1): U_1; }; reduceRight: { (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number): number; (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number, initialValue: number): number; <U_2>(callbackfn: (previousValue: U_2, currentValue: number, currentIndex: number, array: number[]) => U_2, initialValue: U_2): U_2; }; find: { <S_2 extends number>(predicate: (value: number, index: number, obj: number[]) => value is S_2, thisArg?: any): S_2; (predicate: (value: number, index: number, obj: number[]) => unknown, thisArg?: any): number; }; findIndex: (predicate: (value: number, index: number, obj: number[]) => unknown, thisArg?: any) => number; fill: (value: number, start?: number, end?: number) => number[]; copyWithin: (target: number, start: number, end?: number) => number[]; entries: () => IterableIterator<[number, number]>; keys: () => IterableIterator<number>; values: () => IterableIterator<number>; includes: (searchElement: number, fromIndex?: number) => boolean; flatMap: <U_3, This = undefined>(callback: (this: This, value: number, index: number, array: number[]) => U_3 | readonly U_3[], thisArg?: This) => U_3[]; flat: <A, D extends number = 1>(this: A, depth?: D) => FlatArray<A, D>[]; }

View File

@ -0,0 +1,11 @@
mappedTypeWithAsClauseAndLateBoundProperty2.ts(1,14): error TS4118: The type of this node cannot be serialized because its property '[iterator]' cannot be serialized.
mappedTypeWithAsClauseAndLateBoundProperty2.ts(1,14): error TS4118: The type of this node cannot be serialized because its property '[unscopables]' cannot be serialized.
==== mappedTypeWithAsClauseAndLateBoundProperty2.ts (2 errors) ====
export const thing = (null as any as { [K in keyof number[] & PropertyKey as Exclude<K, "length">]: (number[])[K] });
~~~~~
!!! error TS4118: The type of this node cannot be serialized because its property '[iterator]' cannot be serialized.
~~~~~
!!! error TS4118: The type of this node cannot be serialized because its property '[unscopables]' cannot be serialized.

View File

@ -1,213 +1,8 @@
//// [tests/cases/compiler/mappedTypeWithAsClauseAndLateBoundProperty2.ts] ////
//// [mappedTypeWithAsClauseAndLateBoundProperty2.ts]
export const thing = (null as any as { [K in keyof number[] as Exclude<K, "length">]: (number[])[K] });
export const thing = (null as any as { [K in keyof number[] & PropertyKey as Exclude<K, "length">]: (number[])[K] });
//// [mappedTypeWithAsClauseAndLateBoundProperty2.js]
export const thing = null;
//// [mappedTypeWithAsClauseAndLateBoundProperty2.d.ts]
export declare const thing: {
[x: number]: number;
toString: () => string;
toLocaleString: () => string;
pop: () => number;
push: (...items: number[]) => number;
concat: {
(...items: ConcatArray<number>[]): number[];
(...items: (number | ConcatArray<number>)[]): number[];
};
join: (separator?: string) => string;
reverse: () => number[];
shift: () => number;
slice: (start?: number, end?: number) => number[];
sort: (compareFn?: (a: number, b: number) => number) => number[];
splice: {
(start: number, deleteCount?: number): number[];
(start: number, deleteCount: number, ...items: number[]): number[];
};
unshift: (...items: number[]) => number;
indexOf: (searchElement: number, fromIndex?: number) => number;
lastIndexOf: (searchElement: number, fromIndex?: number) => number;
every: {
<S extends number>(predicate: (value: number, index: number, array: number[]) => value is S, thisArg?: any): this is S[];
(predicate: (value: number, index: number, array: number[]) => unknown, thisArg?: any): boolean;
};
some: (predicate: (value: number, index: number, array: number[]) => unknown, thisArg?: any) => boolean;
forEach: (callbackfn: (value: number, index: number, array: number[]) => void, thisArg?: any) => void;
map: <U>(callbackfn: (value: number, index: number, array: number[]) => U, thisArg?: any) => U[];
filter: {
<S_1 extends number>(predicate: (value: number, index: number, array: number[]) => value is S_1, thisArg?: any): S_1[];
(predicate: (value: number, index: number, array: number[]) => unknown, thisArg?: any): number[];
};
reduce: {
(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number): number;
(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number, initialValue: number): number;
<U_1>(callbackfn: (previousValue: U_1, currentValue: number, currentIndex: number, array: number[]) => U_1, initialValue: U_1): U_1;
};
reduceRight: {
(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number): number;
(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number, initialValue: number): number;
<U_2>(callbackfn: (previousValue: U_2, currentValue: number, currentIndex: number, array: number[]) => U_2, initialValue: U_2): U_2;
};
find: {
<S_2 extends number>(predicate: (value: number, index: number, obj: number[]) => value is S_2, thisArg?: any): S_2;
(predicate: (value: number, index: number, obj: number[]) => unknown, thisArg?: any): number;
};
findIndex: (predicate: (value: number, index: number, obj: number[]) => unknown, thisArg?: any) => number;
fill: (value: number, start?: number, end?: number) => number[];
copyWithin: (target: number, start: number, end?: number) => number[];
entries: () => IterableIterator<[number, number]>;
keys: () => IterableIterator<number>;
values: () => IterableIterator<number>;
includes: (searchElement: number, fromIndex?: number) => boolean;
flatMap: <U_3, This = undefined>(callback: (this: This, value: number, index: number, array: number[]) => U_3 | readonly U_3[], thisArg?: This) => U_3[];
flat: <A, D extends number = 1>(this: A, depth?: D) => FlatArray<A, D>[];
[Symbol.iterator]: () => IterableIterator<number>;
readonly [Symbol.unscopables]: {
[x: number]: boolean;
length?: boolean;
toString?: boolean;
toLocaleString?: boolean;
pop?: boolean;
push?: boolean;
concat?: boolean;
join?: boolean;
reverse?: boolean;
shift?: boolean;
slice?: boolean;
sort?: boolean;
splice?: boolean;
unshift?: boolean;
indexOf?: boolean;
lastIndexOf?: boolean;
every?: boolean;
some?: boolean;
forEach?: boolean;
map?: boolean;
filter?: boolean;
reduce?: boolean;
reduceRight?: boolean;
find?: boolean;
findIndex?: boolean;
fill?: boolean;
copyWithin?: boolean;
entries?: boolean;
keys?: boolean;
values?: boolean;
includes?: boolean;
flatMap?: boolean;
flat?: boolean;
[Symbol.iterator]?: boolean;
readonly [Symbol.unscopables]?: boolean;
};
};
//// [DtsFileErrors]
mappedTypeWithAsClauseAndLateBoundProperty2.d.ts(24,118): error TS2526: A 'this' type is available only in a non-static member of a class or interface.
==== mappedTypeWithAsClauseAndLateBoundProperty2.d.ts (1 errors) ====
export declare const thing: {
[x: number]: number;
toString: () => string;
toLocaleString: () => string;
pop: () => number;
push: (...items: number[]) => number;
concat: {
(...items: ConcatArray<number>[]): number[];
(...items: (number | ConcatArray<number>)[]): number[];
};
join: (separator?: string) => string;
reverse: () => number[];
shift: () => number;
slice: (start?: number, end?: number) => number[];
sort: (compareFn?: (a: number, b: number) => number) => number[];
splice: {
(start: number, deleteCount?: number): number[];
(start: number, deleteCount: number, ...items: number[]): number[];
};
unshift: (...items: number[]) => number;
indexOf: (searchElement: number, fromIndex?: number) => number;
lastIndexOf: (searchElement: number, fromIndex?: number) => number;
every: {
<S extends number>(predicate: (value: number, index: number, array: number[]) => value is S, thisArg?: any): this is S[];
~~~~
!!! error TS2526: A 'this' type is available only in a non-static member of a class or interface.
(predicate: (value: number, index: number, array: number[]) => unknown, thisArg?: any): boolean;
};
some: (predicate: (value: number, index: number, array: number[]) => unknown, thisArg?: any) => boolean;
forEach: (callbackfn: (value: number, index: number, array: number[]) => void, thisArg?: any) => void;
map: <U>(callbackfn: (value: number, index: number, array: number[]) => U, thisArg?: any) => U[];
filter: {
<S_1 extends number>(predicate: (value: number, index: number, array: number[]) => value is S_1, thisArg?: any): S_1[];
(predicate: (value: number, index: number, array: number[]) => unknown, thisArg?: any): number[];
};
reduce: {
(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number): number;
(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number, initialValue: number): number;
<U_1>(callbackfn: (previousValue: U_1, currentValue: number, currentIndex: number, array: number[]) => U_1, initialValue: U_1): U_1;
};
reduceRight: {
(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number): number;
(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number, initialValue: number): number;
<U_2>(callbackfn: (previousValue: U_2, currentValue: number, currentIndex: number, array: number[]) => U_2, initialValue: U_2): U_2;
};
find: {
<S_2 extends number>(predicate: (value: number, index: number, obj: number[]) => value is S_2, thisArg?: any): S_2;
(predicate: (value: number, index: number, obj: number[]) => unknown, thisArg?: any): number;
};
findIndex: (predicate: (value: number, index: number, obj: number[]) => unknown, thisArg?: any) => number;
fill: (value: number, start?: number, end?: number) => number[];
copyWithin: (target: number, start: number, end?: number) => number[];
entries: () => IterableIterator<[number, number]>;
keys: () => IterableIterator<number>;
values: () => IterableIterator<number>;
includes: (searchElement: number, fromIndex?: number) => boolean;
flatMap: <U_3, This = undefined>(callback: (this: This, value: number, index: number, array: number[]) => U_3 | readonly U_3[], thisArg?: This) => U_3[];
flat: <A, D extends number = 1>(this: A, depth?: D) => FlatArray<A, D>[];
[Symbol.iterator]: () => IterableIterator<number>;
readonly [Symbol.unscopables]: {
[x: number]: boolean;
length?: boolean;
toString?: boolean;
toLocaleString?: boolean;
pop?: boolean;
push?: boolean;
concat?: boolean;
join?: boolean;
reverse?: boolean;
shift?: boolean;
slice?: boolean;
sort?: boolean;
splice?: boolean;
unshift?: boolean;
indexOf?: boolean;
lastIndexOf?: boolean;
every?: boolean;
some?: boolean;
forEach?: boolean;
map?: boolean;
filter?: boolean;
reduce?: boolean;
reduceRight?: boolean;
find?: boolean;
findIndex?: boolean;
fill?: boolean;
copyWithin?: boolean;
entries?: boolean;
keys?: boolean;
values?: boolean;
includes?: boolean;
flatMap?: boolean;
flat?: boolean;
[Symbol.iterator]?: boolean;
readonly [Symbol.unscopables]?: boolean;
};
};

View File

@ -1,9 +1,10 @@
//// [tests/cases/compiler/mappedTypeWithAsClauseAndLateBoundProperty2.ts] ////
=== mappedTypeWithAsClauseAndLateBoundProperty2.ts ===
export const thing = (null as any as { [K in keyof number[] as Exclude<K, "length">]: (number[])[K] });
export const thing = (null as any as { [K in keyof number[] & PropertyKey as Exclude<K, "length">]: (number[])[K] });
>thing : Symbol(thing, Decl(mappedTypeWithAsClauseAndLateBoundProperty2.ts, 0, 12))
>K : Symbol(K, Decl(mappedTypeWithAsClauseAndLateBoundProperty2.ts, 0, 40))
>PropertyKey : Symbol(PropertyKey, Decl(lib.es5.d.ts, --, --))
>Exclude : Symbol(Exclude, Decl(lib.es5.d.ts, --, --))
>K : Symbol(K, Decl(mappedTypeWithAsClauseAndLateBoundProperty2.ts, 0, 40))
>K : Symbol(K, Decl(mappedTypeWithAsClauseAndLateBoundProperty2.ts, 0, 40))

View File

@ -1,9 +1,9 @@
//// [tests/cases/compiler/mappedTypeWithAsClauseAndLateBoundProperty2.ts] ////
=== mappedTypeWithAsClauseAndLateBoundProperty2.ts ===
export const thing = (null as any as { [K in keyof number[] as Exclude<K, "length">]: (number[])[K] });
>thing : { [x: number]: number; toString: () => string; toLocaleString: () => string; pop: () => number; push: (...items: number[]) => number; concat: { (...items: ConcatArray<number>[]): number[]; (...items: (number | ConcatArray<number>)[]): number[]; }; join: (separator?: string) => string; reverse: () => number[]; shift: () => number; slice: (start?: number, end?: number) => number[]; sort: (compareFn?: (a: number, b: number) => number) => number[]; splice: { (start: number, deleteCount?: number): number[]; (start: number, deleteCount: number, ...items: number[]): number[]; }; unshift: (...items: number[]) => number; indexOf: (searchElement: number, fromIndex?: number) => number; lastIndexOf: (searchElement: number, fromIndex?: number) => number; every: { <S extends number>(predicate: (value: number, index: number, array: number[]) => value is S, thisArg?: any): this is S[]; (predicate: (value: number, index: number, array: number[]) => unknown, thisArg?: any): boolean; }; some: (predicate: (value: number, index: number, array: number[]) => unknown, thisArg?: any) => boolean; forEach: (callbackfn: (value: number, index: number, array: number[]) => void, thisArg?: any) => void; map: <U>(callbackfn: (value: number, index: number, array: number[]) => U, thisArg?: any) => U[]; filter: { <S_1 extends number>(predicate: (value: number, index: number, array: number[]) => value is S_1, thisArg?: any): S_1[]; (predicate: (value: number, index: number, array: number[]) => unknown, thisArg?: any): number[]; }; reduce: { (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number): number; (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number, initialValue: number): number; <U_1>(callbackfn: (previousValue: U_1, currentValue: number, currentIndex: number, array: number[]) => U_1, initialValue: U_1): U_1; }; reduceRight: { (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number): number; (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number, initialValue: number): number; <U_2>(callbackfn: (previousValue: U_2, currentValue: number, currentIndex: number, array: number[]) => U_2, initialValue: U_2): U_2; }; find: { <S_2 extends number>(predicate: (value: number, index: number, obj: number[]) => value is S_2, thisArg?: any): S_2; (predicate: (value: number, index: number, obj: number[]) => unknown, thisArg?: any): number; }; findIndex: (predicate: (value: number, index: number, obj: number[]) => unknown, thisArg?: any) => number; fill: (value: number, start?: number, end?: number) => number[]; copyWithin: (target: number, start: number, end?: number) => number[]; entries: () => IterableIterator<[number, number]>; keys: () => IterableIterator<number>; values: () => IterableIterator<number>; includes: (searchElement: number, fromIndex?: number) => boolean; flatMap: <U_3, This = undefined>(callback: (this: This, value: number, index: number, array: number[]) => U_3 | readonly U_3[], thisArg?: This) => U_3[]; flat: <A, D extends number = 1>(this: A, depth?: D) => FlatArray<A, D>[]; [Symbol.iterator]: () => IterableIterator<number>; readonly [Symbol.unscopables]: { [x: number]: boolean; length?: boolean; toString?: boolean; toLocaleString?: boolean; pop?: boolean; push?: boolean; concat?: boolean; join?: boolean; reverse?: boolean; shift?: boolean; slice?: boolean; sort?: boolean; splice?: boolean; unshift?: boolean; indexOf?: boolean; lastIndexOf?: boolean; every?: boolean; some?: boolean; forEach?: boolean; map?: boolean; filter?: boolean; reduce?: boolean; reduceRight?: boolean; find?: boolean; findIndex?: boolean; fill?: boolean; copyWithin?: boolean; entries?: boolean; keys?: boolean; values?: boolean; includes?: boolean; flatMap?: boolean; flat?: boolean; [Symbol.iterator]?: boolean; readonly [Symbol.unscopables]?: boolean; }; }
>(null as any as { [K in keyof number[] as Exclude<K, "length">]: (number[])[K] }) : { [x: number]: number; toString: () => string; toLocaleString: () => string; pop: () => number; push: (...items: number[]) => number; concat: { (...items: ConcatArray<number>[]): number[]; (...items: (number | ConcatArray<number>)[]): number[]; }; join: (separator?: string) => string; reverse: () => number[]; shift: () => number; slice: (start?: number, end?: number) => number[]; sort: (compareFn?: (a: number, b: number) => number) => number[]; splice: { (start: number, deleteCount?: number): number[]; (start: number, deleteCount: number, ...items: number[]): number[]; }; unshift: (...items: number[]) => number; indexOf: (searchElement: number, fromIndex?: number) => number; lastIndexOf: (searchElement: number, fromIndex?: number) => number; every: { <S extends number>(predicate: (value: number, index: number, array: number[]) => value is S, thisArg?: any): this is S[]; (predicate: (value: number, index: number, array: number[]) => unknown, thisArg?: any): boolean; }; some: (predicate: (value: number, index: number, array: number[]) => unknown, thisArg?: any) => boolean; forEach: (callbackfn: (value: number, index: number, array: number[]) => void, thisArg?: any) => void; map: <U>(callbackfn: (value: number, index: number, array: number[]) => U, thisArg?: any) => U[]; filter: { <S_1 extends number>(predicate: (value: number, index: number, array: number[]) => value is S_1, thisArg?: any): S_1[]; (predicate: (value: number, index: number, array: number[]) => unknown, thisArg?: any): number[]; }; reduce: { (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number): number; (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number, initialValue: number): number; <U_1>(callbackfn: (previousValue: U_1, currentValue: number, currentIndex: number, array: number[]) => U_1, initialValue: U_1): U_1; }; reduceRight: { (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number): number; (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number, initialValue: number): number; <U_2>(callbackfn: (previousValue: U_2, currentValue: number, currentIndex: number, array: number[]) => U_2, initialValue: U_2): U_2; }; find: { <S_2 extends number>(predicate: (value: number, index: number, obj: number[]) => value is S_2, thisArg?: any): S_2; (predicate: (value: number, index: number, obj: number[]) => unknown, thisArg?: any): number; }; findIndex: (predicate: (value: number, index: number, obj: number[]) => unknown, thisArg?: any) => number; fill: (value: number, start?: number, end?: number) => number[]; copyWithin: (target: number, start: number, end?: number) => number[]; entries: () => IterableIterator<[number, number]>; keys: () => IterableIterator<number>; values: () => IterableIterator<number>; includes: (searchElement: number, fromIndex?: number) => boolean; flatMap: <U_3, This = undefined>(callback: (this: This, value: number, index: number, array: number[]) => U_3 | readonly U_3[], thisArg?: This) => U_3[]; flat: <A, D extends number = 1>(this: A, depth?: D) => FlatArray<A, D>[]; [Symbol.iterator]: () => IterableIterator<number>; readonly [Symbol.unscopables]: { [x: number]: boolean; length?: boolean; toString?: boolean; toLocaleString?: boolean; pop?: boolean; push?: boolean; concat?: boolean; join?: boolean; reverse?: boolean; shift?: boolean; slice?: boolean; sort?: boolean; splice?: boolean; unshift?: boolean; indexOf?: boolean; lastIndexOf?: boolean; every?: boolean; some?: boolean; forEach?: boolean; map?: boolean; filter?: boolean; reduce?: boolean; reduceRight?: boolean; find?: boolean; findIndex?: boolean; fill?: boolean; copyWithin?: boolean; entries?: boolean; keys?: boolean; values?: boolean; includes?: boolean; flatMap?: boolean; flat?: boolean; [Symbol.iterator]?: boolean; readonly [Symbol.unscopables]?: boolean; }; }
>null as any as { [K in keyof number[] as Exclude<K, "length">]: (number[])[K] } : { [x: number]: number; toString: () => string; toLocaleString: () => string; pop: () => number; push: (...items: number[]) => number; concat: { (...items: ConcatArray<number>[]): number[]; (...items: (number | ConcatArray<number>)[]): number[]; }; join: (separator?: string) => string; reverse: () => number[]; shift: () => number; slice: (start?: number, end?: number) => number[]; sort: (compareFn?: (a: number, b: number) => number) => number[]; splice: { (start: number, deleteCount?: number): number[]; (start: number, deleteCount: number, ...items: number[]): number[]; }; unshift: (...items: number[]) => number; indexOf: (searchElement: number, fromIndex?: number) => number; lastIndexOf: (searchElement: number, fromIndex?: number) => number; every: { <S extends number>(predicate: (value: number, index: number, array: number[]) => value is S, thisArg?: any): this is S[]; (predicate: (value: number, index: number, array: number[]) => unknown, thisArg?: any): boolean; }; some: (predicate: (value: number, index: number, array: number[]) => unknown, thisArg?: any) => boolean; forEach: (callbackfn: (value: number, index: number, array: number[]) => void, thisArg?: any) => void; map: <U>(callbackfn: (value: number, index: number, array: number[]) => U, thisArg?: any) => U[]; filter: { <S_1 extends number>(predicate: (value: number, index: number, array: number[]) => value is S_1, thisArg?: any): S_1[]; (predicate: (value: number, index: number, array: number[]) => unknown, thisArg?: any): number[]; }; reduce: { (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number): number; (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number, initialValue: number): number; <U_1>(callbackfn: (previousValue: U_1, currentValue: number, currentIndex: number, array: number[]) => U_1, initialValue: U_1): U_1; }; reduceRight: { (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number): number; (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number, initialValue: number): number; <U_2>(callbackfn: (previousValue: U_2, currentValue: number, currentIndex: number, array: number[]) => U_2, initialValue: U_2): U_2; }; find: { <S_2 extends number>(predicate: (value: number, index: number, obj: number[]) => value is S_2, thisArg?: any): S_2; (predicate: (value: number, index: number, obj: number[]) => unknown, thisArg?: any): number; }; findIndex: (predicate: (value: number, index: number, obj: number[]) => unknown, thisArg?: any) => number; fill: (value: number, start?: number, end?: number) => number[]; copyWithin: (target: number, start: number, end?: number) => number[]; entries: () => IterableIterator<[number, number]>; keys: () => IterableIterator<number>; values: () => IterableIterator<number>; includes: (searchElement: number, fromIndex?: number) => boolean; flatMap: <U_3, This = undefined>(callback: (this: This, value: number, index: number, array: number[]) => U_3 | readonly U_3[], thisArg?: This) => U_3[]; flat: <A, D extends number = 1>(this: A, depth?: D) => FlatArray<A, D>[]; [Symbol.iterator]: () => IterableIterator<number>; readonly [Symbol.unscopables]: { [x: number]: boolean; length?: boolean; toString?: boolean; toLocaleString?: boolean; pop?: boolean; push?: boolean; concat?: boolean; join?: boolean; reverse?: boolean; shift?: boolean; slice?: boolean; sort?: boolean; splice?: boolean; unshift?: boolean; indexOf?: boolean; lastIndexOf?: boolean; every?: boolean; some?: boolean; forEach?: boolean; map?: boolean; filter?: boolean; reduce?: boolean; reduceRight?: boolean; find?: boolean; findIndex?: boolean; fill?: boolean; copyWithin?: boolean; entries?: boolean; keys?: boolean; values?: boolean; includes?: boolean; flatMap?: boolean; flat?: boolean; [Symbol.iterator]?: boolean; readonly [Symbol.unscopables]?: boolean; }; }
export const thing = (null as any as { [K in keyof number[] & PropertyKey as Exclude<K, "length">]: (number[])[K] });
>thing : { [x: number]: number; [Symbol.iterator]: () => IterableIterator<number>; [Symbol.unscopables]: { [x: number]: boolean; }; toString: () => string; toLocaleString: () => string; pop: () => number; push: (...items: number[]) => number; concat: { (...items: ConcatArray<number>[]): number[]; (...items: (number | ConcatArray<number>)[]): number[]; }; join: (separator?: string) => string; reverse: () => number[]; shift: () => number; slice: (start?: number, end?: number) => number[]; sort: (compareFn?: (a: number, b: number) => number) => number[]; splice: { (start: number, deleteCount?: number): number[]; (start: number, deleteCount: number, ...items: number[]): number[]; }; unshift: (...items: number[]) => number; indexOf: (searchElement: number, fromIndex?: number) => number; lastIndexOf: (searchElement: number, fromIndex?: number) => number; every: { <S extends number>(predicate: (value: number, index: number, array: number[]) => value is S, thisArg?: any): this is S[]; (predicate: (value: number, index: number, array: number[]) => unknown, thisArg?: any): boolean; }; some: (predicate: (value: number, index: number, array: number[]) => unknown, thisArg?: any) => boolean; forEach: (callbackfn: (value: number, index: number, array: number[]) => void, thisArg?: any) => void; map: <U>(callbackfn: (value: number, index: number, array: number[]) => U, thisArg?: any) => U[]; filter: { <S_1 extends number>(predicate: (value: number, index: number, array: number[]) => value is S_1, thisArg?: any): S_1[]; (predicate: (value: number, index: number, array: number[]) => unknown, thisArg?: any): number[]; }; reduce: { (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number): number; (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number, initialValue: number): number; <U_1>(callbackfn: (previousValue: U_1, currentValue: number, currentIndex: number, array: number[]) => U_1, initialValue: U_1): U_1; }; reduceRight: { (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number): number; (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number, initialValue: number): number; <U_2>(callbackfn: (previousValue: U_2, currentValue: number, currentIndex: number, array: number[]) => U_2, initialValue: U_2): U_2; }; find: { <S_2 extends number>(predicate: (value: number, index: number, obj: number[]) => value is S_2, thisArg?: any): S_2; (predicate: (value: number, index: number, obj: number[]) => unknown, thisArg?: any): number; }; findIndex: (predicate: (value: number, index: number, obj: number[]) => unknown, thisArg?: any) => number; fill: (value: number, start?: number, end?: number) => number[]; copyWithin: (target: number, start: number, end?: number) => number[]; entries: () => IterableIterator<[number, number]>; keys: () => IterableIterator<number>; values: () => IterableIterator<number>; includes: (searchElement: number, fromIndex?: number) => boolean; flatMap: <U_3, This = undefined>(callback: (this: This, value: number, index: number, array: number[]) => U_3 | readonly U_3[], thisArg?: This) => U_3[]; flat: <A, D extends number = 1>(this: A, depth?: D) => FlatArray<A, D>[]; }
>(null as any as { [K in keyof number[] & PropertyKey as Exclude<K, "length">]: (number[])[K] }) : { [x: number]: number; [Symbol.iterator]: () => IterableIterator<number>; [Symbol.unscopables]: { [x: number]: boolean; }; toString: () => string; toLocaleString: () => string; pop: () => number; push: (...items: number[]) => number; concat: { (...items: ConcatArray<number>[]): number[]; (...items: (number | ConcatArray<number>)[]): number[]; }; join: (separator?: string) => string; reverse: () => number[]; shift: () => number; slice: (start?: number, end?: number) => number[]; sort: (compareFn?: (a: number, b: number) => number) => number[]; splice: { (start: number, deleteCount?: number): number[]; (start: number, deleteCount: number, ...items: number[]): number[]; }; unshift: (...items: number[]) => number; indexOf: (searchElement: number, fromIndex?: number) => number; lastIndexOf: (searchElement: number, fromIndex?: number) => number; every: { <S extends number>(predicate: (value: number, index: number, array: number[]) => value is S, thisArg?: any): this is S[]; (predicate: (value: number, index: number, array: number[]) => unknown, thisArg?: any): boolean; }; some: (predicate: (value: number, index: number, array: number[]) => unknown, thisArg?: any) => boolean; forEach: (callbackfn: (value: number, index: number, array: number[]) => void, thisArg?: any) => void; map: <U>(callbackfn: (value: number, index: number, array: number[]) => U, thisArg?: any) => U[]; filter: { <S_1 extends number>(predicate: (value: number, index: number, array: number[]) => value is S_1, thisArg?: any): S_1[]; (predicate: (value: number, index: number, array: number[]) => unknown, thisArg?: any): number[]; }; reduce: { (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number): number; (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number, initialValue: number): number; <U_1>(callbackfn: (previousValue: U_1, currentValue: number, currentIndex: number, array: number[]) => U_1, initialValue: U_1): U_1; }; reduceRight: { (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number): number; (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number, initialValue: number): number; <U_2>(callbackfn: (previousValue: U_2, currentValue: number, currentIndex: number, array: number[]) => U_2, initialValue: U_2): U_2; }; find: { <S_2 extends number>(predicate: (value: number, index: number, obj: number[]) => value is S_2, thisArg?: any): S_2; (predicate: (value: number, index: number, obj: number[]) => unknown, thisArg?: any): number; }; findIndex: (predicate: (value: number, index: number, obj: number[]) => unknown, thisArg?: any) => number; fill: (value: number, start?: number, end?: number) => number[]; copyWithin: (target: number, start: number, end?: number) => number[]; entries: () => IterableIterator<[number, number]>; keys: () => IterableIterator<number>; values: () => IterableIterator<number>; includes: (searchElement: number, fromIndex?: number) => boolean; flatMap: <U_3, This = undefined>(callback: (this: This, value: number, index: number, array: number[]) => U_3 | readonly U_3[], thisArg?: This) => U_3[]; flat: <A, D extends number = 1>(this: A, depth?: D) => FlatArray<A, D>[]; }
>null as any as { [K in keyof number[] & PropertyKey as Exclude<K, "length">]: (number[])[K] } : { [x: number]: number; [Symbol.iterator]: () => IterableIterator<number>; [Symbol.unscopables]: { [x: number]: boolean; }; toString: () => string; toLocaleString: () => string; pop: () => number; push: (...items: number[]) => number; concat: { (...items: ConcatArray<number>[]): number[]; (...items: (number | ConcatArray<number>)[]): number[]; }; join: (separator?: string) => string; reverse: () => number[]; shift: () => number; slice: (start?: number, end?: number) => number[]; sort: (compareFn?: (a: number, b: number) => number) => number[]; splice: { (start: number, deleteCount?: number): number[]; (start: number, deleteCount: number, ...items: number[]): number[]; }; unshift: (...items: number[]) => number; indexOf: (searchElement: number, fromIndex?: number) => number; lastIndexOf: (searchElement: number, fromIndex?: number) => number; every: { <S extends number>(predicate: (value: number, index: number, array: number[]) => value is S, thisArg?: any): this is S[]; (predicate: (value: number, index: number, array: number[]) => unknown, thisArg?: any): boolean; }; some: (predicate: (value: number, index: number, array: number[]) => unknown, thisArg?: any) => boolean; forEach: (callbackfn: (value: number, index: number, array: number[]) => void, thisArg?: any) => void; map: <U>(callbackfn: (value: number, index: number, array: number[]) => U, thisArg?: any) => U[]; filter: { <S_1 extends number>(predicate: (value: number, index: number, array: number[]) => value is S_1, thisArg?: any): S_1[]; (predicate: (value: number, index: number, array: number[]) => unknown, thisArg?: any): number[]; }; reduce: { (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number): number; (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number, initialValue: number): number; <U_1>(callbackfn: (previousValue: U_1, currentValue: number, currentIndex: number, array: number[]) => U_1, initialValue: U_1): U_1; }; reduceRight: { (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number): number; (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number, initialValue: number): number; <U_2>(callbackfn: (previousValue: U_2, currentValue: number, currentIndex: number, array: number[]) => U_2, initialValue: U_2): U_2; }; find: { <S_2 extends number>(predicate: (value: number, index: number, obj: number[]) => value is S_2, thisArg?: any): S_2; (predicate: (value: number, index: number, obj: number[]) => unknown, thisArg?: any): number; }; findIndex: (predicate: (value: number, index: number, obj: number[]) => unknown, thisArg?: any) => number; fill: (value: number, start?: number, end?: number) => number[]; copyWithin: (target: number, start: number, end?: number) => number[]; entries: () => IterableIterator<[number, number]>; keys: () => IterableIterator<number>; values: () => IterableIterator<number>; includes: (searchElement: number, fromIndex?: number) => boolean; flatMap: <U_3, This = undefined>(callback: (this: This, value: number, index: number, array: number[]) => U_3 | readonly U_3[], thisArg?: This) => U_3[]; flat: <A, D extends number = 1>(this: A, depth?: D) => FlatArray<A, D>[]; }
>null as any : any

View File

@ -0,0 +1,13 @@
// @strict: true
// @noEmit: true
// https://github.com/microsoft/TypeScript/pull/55774#issuecomment-1813484949
type Mapper<T> = {
[K in keyof T as K]: T[K] extends NonNullable<T[K]> ? T[K] : never;
};
type Mapped = Mapper<[1, 2]>;
type Keys = keyof Mapper<[1, 2]>;
type SomeType = Mapped[Keys]; // ok

View File

@ -0,0 +1,50 @@
// @strict: true
// @noEmit: true
// based on https://github.com/microsoft/TypeScript/issues/55762
declare class Decoder<T> {
decode(arrayBuffer: ArrayBuffer): T;
}
type ValueTypeOf<T extends Decoder<any>> = T extends Decoder<infer R>
? R
: never;
type StructDescriptor = ReadonlyArray<
readonly [key: string, type: Decoder<any>]
>;
type StructTypeFor<Descriptor extends StructDescriptor> = {
[K in keyof Descriptor as Descriptor[K][0]]: ValueTypeOf<Descriptor[K][1]>;
};
class StructDecoder<const Descriptor extends StructDescriptor> extends Decoder<
StructTypeFor<Descriptor>
> {
constructor(descriptor: Descriptor) {
super();
}
}
declare const i32Decoder: Decoder<number>;
declare const i64Decoder: Decoder<bigint>;
const structDecoder1 = new StructDecoder([
["a", i32Decoder],
["b", i64Decoder],
]);
const struct1 = structDecoder1.decode(new ArrayBuffer(100));
const v1_1: number = struct1.a;
const v1_2: bigint = struct1.b;
declare const descriptor2: [["a", Decoder<number>], ["b", Decoder<string>], ...["c", Decoder<bigint>][]]
const structDecoder2 = new StructDecoder(descriptor2);
const struct2 = structDecoder2.decode(new ArrayBuffer(100));
const v2_1: number = struct2.a;
const v2_2: string = struct2.b;
const v2_3: bigint = struct2.c;

View File

@ -1,4 +1,4 @@
// @target: ES2020
declare let tgt2: number[];
declare let src2: { [K in keyof number[] as Exclude<K, "length">]: (number[])[K] };
declare let src2: { [K in keyof number[] & PropertyKey as Exclude<K, "length">]: (number[])[K] };
tgt2 = src2; // Should error

View File

@ -1,3 +1,3 @@
// @target: ES2020
// @declaration: true
export const thing = (null as any as { [K in keyof number[] as Exclude<K, "length">]: (number[])[K] });
export const thing = (null as any as { [K in keyof number[] & PropertyKey as Exclude<K, "length">]: (number[])[K] });