Adding tests

This commit is contained in:
Anders Hejlsberg 2016-11-02 09:13:45 -07:00
parent 70fc25a45a
commit 4bbe29ab73
7 changed files with 2071 additions and 0 deletions

View file

@ -0,0 +1,350 @@
//// [keyofAndIndexedAccess.ts]
class Shape {
name: string;
width: number;
height: number;
visible: boolean;
}
class Item {
name: string;
price: number;
}
class Options {
visible: "yes" | "no";
}
type Dictionary<T> = { [x: string]: T };
const enum E { A, B, C }
type K00 = keyof any; // string | number
type K01 = keyof string; // number | "toString" | "charAt" | ...
type K02 = keyof number; // "toString" | "toFixed" | "toExponential" | ...
type K03 = keyof boolean; // "valueOf"
type K04 = keyof void; // never
type K05 = keyof undefined; // never
type K06 = keyof null; // never
type K07 = keyof never; // never
type K10 = keyof Shape; // "name" | "width" | "height" | "visible"
type K11 = keyof Shape[]; // number | "length" | "toString" | ...
type K12 = keyof Dictionary<Shape>; // string | number
type K13 = keyof {}; // never
type K14 = keyof Object; // "constructor" | "toString" | ...
type K15 = keyof E; // "toString" | "toFixed" | "toExponential" | ...
type K16 = keyof [string, number]; // number | "0" | "1" | "length" | "toString" | ...
type K17 = keyof (Shape | Item); // "name"
type K18 = keyof (Shape & Item); // "name" | "width" | "height" | "visible" | "price"
type KeyOf<T> = keyof T;
type K20 = KeyOf<Shape>; // "name" | "width" | "height" | "visible"
type K21 = KeyOf<Dictionary<Shape>>; // string | number
type NAME = "name";
type WIDTH_OR_HEIGHT = "width" | "height";
type Q10 = Shape["name"]; // string
type Q11 = Shape["width" | "height"]; // number
type Q12 = Shape["name" | "visible"]; // string | boolean
type Q20 = Shape[NAME]; // string
type Q21 = Shape[WIDTH_OR_HEIGHT]; // number
type Q30 = [string, number][0]; // string
type Q31 = [string, number][1]; // number
type Q32 = [string, number][2]; // string | number
type Q33 = [string, number][E.A]; // string
type Q34 = [string, number][E.B]; // number
type Q35 = [string, number][E.C]; // string | number
type Q36 = [string, number]["0"]; // string
type Q37 = [string, number]["1"]; // string
type Q40 = (Shape | Options)["visible"]; // boolean | "yes" | "no"
type Q41 = (Shape & Options)["visible"]; // true & "yes" | true & "no" | false & "yes" | false & "no"
type Q50 = Dictionary<Shape>["howdy"]; // Shape
type Q51 = Dictionary<Shape>[123]; // Shape
type Q52 = Dictionary<Shape>[E.B]; // Shape
declare let cond: boolean;
function getProperty<T, K extends keyof T>(obj: T, key: K) {
return obj[key];
}
function setProperty<T, K extends keyof T>(obj: T, key: K, value: T[K]) {
obj[key] = value;
}
function f10(shape: Shape) {
let name = getProperty(shape, "name"); // string
let widthOrHeight = getProperty(shape, cond ? "width" : "height"); // number
let nameOrVisible = getProperty(shape, cond ? "name" : "visible"); // string | boolean
setProperty(shape, "name", "rectangle");
setProperty(shape, cond ? "width" : "height", 10);
setProperty(shape, cond ? "name" : "visible", true); // Technically not safe
}
function f11(a: Shape[]) {
let len = getProperty(a, "length"); // number
let shape = getProperty(a, 1000); // Shape
setProperty(a, 1000, getProperty(a, 1001));
}
function f12(t: [Shape, boolean]) {
let len = getProperty(t, "length");
let s1 = getProperty(t, 0); // Shape
let s2 = getProperty(t, "0"); // Shape
let b1 = getProperty(t, 1); // boolean
let b2 = getProperty(t, "1"); // boolean
let x1 = getProperty(t, 2); // Shape | boolean
}
function f13(foo: any, bar: any) {
let x = getProperty(foo, "x"); // any
let y = getProperty(foo, 100); // any
let z = getProperty(foo, bar); // any
}
class Component<PropType> {
props: PropType;
getProperty<K extends keyof PropType>(key: K) {
return this.props[key];
}
setProperty<K extends keyof PropType>(key: K, value: PropType[K]) {
this.props[key] = value;
}
}
function f20(component: Component<Shape>) {
let name = component.getProperty("name"); // string
let widthOrHeight = component.getProperty(cond ? "width" : "height"); // number
let nameOrVisible = component.getProperty(cond ? "name" : "visible"); // string | boolean
component.setProperty("name", "rectangle");
component.setProperty(cond ? "width" : "height", 10)
component.setProperty(cond ? "name" : "visible", true); // Technically not safe
}
function pluck<T, K extends keyof T>(array: T[], key: K) {
return array.map(x => x[key]);
}
function f30(shapes: Shape[]) {
let names = pluck(shapes, "name"); // string[]
let widths = pluck(shapes, "width"); // number[]
let nameOrVisibles = pluck(shapes, cond ? "name" : "visible"); // (string | boolean)[]
}
function f31<K extends keyof Shape>(key: K) {
const shape: Shape = { name: "foo", width: 5, height: 10, visible: true };
return shape[key]; // Shape[K]
}
function f32<K extends "width" | "height">(key: K) {
const shape: Shape = { name: "foo", width: 5, height: 10, visible: true };
return shape[key]; // Shape[K]
}
class C {
public x: string;
protected y: string;
private z: string;
}
// Indexed access expressions have always permitted access to private and protected members.
// For consistency we also permit such access in indexed access types.
function f40(c: C) {
type X = C["x"];
type Y = C["y"];
type Z = C["z"];
let x: X = c["x"];
let y: Y = c["y"];
let z: Z = c["z"];
}
//// [keyofAndIndexedAccess.js]
var Shape = (function () {
function Shape() {
}
return Shape;
}());
var Item = (function () {
function Item() {
}
return Item;
}());
var Options = (function () {
function Options() {
}
return Options;
}());
function getProperty(obj, key) {
return obj[key];
}
function setProperty(obj, key, value) {
obj[key] = value;
}
function f10(shape) {
var name = getProperty(shape, "name"); // string
var widthOrHeight = getProperty(shape, cond ? "width" : "height"); // number
var nameOrVisible = getProperty(shape, cond ? "name" : "visible"); // string | boolean
setProperty(shape, "name", "rectangle");
setProperty(shape, cond ? "width" : "height", 10);
setProperty(shape, cond ? "name" : "visible", true); // Technically not safe
}
function f11(a) {
var len = getProperty(a, "length"); // number
var shape = getProperty(a, 1000); // Shape
setProperty(a, 1000, getProperty(a, 1001));
}
function f12(t) {
var len = getProperty(t, "length");
var s1 = getProperty(t, 0); // Shape
var s2 = getProperty(t, "0"); // Shape
var b1 = getProperty(t, 1); // boolean
var b2 = getProperty(t, "1"); // boolean
var x1 = getProperty(t, 2); // Shape | boolean
}
function f13(foo, bar) {
var x = getProperty(foo, "x"); // any
var y = getProperty(foo, 100); // any
var z = getProperty(foo, bar); // any
}
var Component = (function () {
function Component() {
}
Component.prototype.getProperty = function (key) {
return this.props[key];
};
Component.prototype.setProperty = function (key, value) {
this.props[key] = value;
};
return Component;
}());
function f20(component) {
var name = component.getProperty("name"); // string
var widthOrHeight = component.getProperty(cond ? "width" : "height"); // number
var nameOrVisible = component.getProperty(cond ? "name" : "visible"); // string | boolean
component.setProperty("name", "rectangle");
component.setProperty(cond ? "width" : "height", 10);
component.setProperty(cond ? "name" : "visible", true); // Technically not safe
}
function pluck(array, key) {
return array.map(function (x) { return x[key]; });
}
function f30(shapes) {
var names = pluck(shapes, "name"); // string[]
var widths = pluck(shapes, "width"); // number[]
var nameOrVisibles = pluck(shapes, cond ? "name" : "visible"); // (string | boolean)[]
}
function f31(key) {
var shape = { name: "foo", width: 5, height: 10, visible: true };
return shape[key]; // Shape[K]
}
function f32(key) {
var shape = { name: "foo", width: 5, height: 10, visible: true };
return shape[key]; // Shape[K]
}
var C = (function () {
function C() {
}
return C;
}());
// Indexed access expressions have always permitted access to private and protected members.
// For consistency we also permit such access in indexed access types.
function f40(c) {
var x = c["x"];
var y = c["y"];
var z = c["z"];
}
//// [keyofAndIndexedAccess.d.ts]
declare class Shape {
name: string;
width: number;
height: number;
visible: boolean;
}
declare class Item {
name: string;
price: number;
}
declare class Options {
visible: "yes" | "no";
}
declare type Dictionary<T> = {
[x: string]: T;
};
declare const enum E {
A = 0,
B = 1,
C = 2,
}
declare type K00 = keyof any;
declare type K01 = keyof string;
declare type K02 = keyof number;
declare type K03 = keyof boolean;
declare type K04 = keyof void;
declare type K05 = keyof undefined;
declare type K06 = keyof null;
declare type K07 = keyof never;
declare type K10 = keyof Shape;
declare type K11 = keyof Shape[];
declare type K12 = keyof Dictionary<Shape>;
declare type K13 = keyof {};
declare type K14 = keyof Object;
declare type K15 = keyof E;
declare type K16 = keyof [string, number];
declare type K17 = keyof (Shape | Item);
declare type K18 = keyof (Shape & Item);
declare type KeyOf<T> = keyof T;
declare type K20 = KeyOf<Shape>;
declare type K21 = KeyOf<Dictionary<Shape>>;
declare type NAME = "name";
declare type WIDTH_OR_HEIGHT = "width" | "height";
declare type Q10 = Shape["name"];
declare type Q11 = Shape["width" | "height"];
declare type Q12 = Shape["name" | "visible"];
declare type Q20 = Shape[NAME];
declare type Q21 = Shape[WIDTH_OR_HEIGHT];
declare type Q30 = [string, number][0];
declare type Q31 = [string, number][1];
declare type Q32 = [string, number][2];
declare type Q33 = [string, number][E.A];
declare type Q34 = [string, number][E.B];
declare type Q35 = [string, number][E.C];
declare type Q36 = [string, number]["0"];
declare type Q37 = [string, number]["1"];
declare type Q40 = (Shape | Options)["visible"];
declare type Q41 = (Shape & Options)["visible"];
declare type Q50 = Dictionary<Shape>["howdy"];
declare type Q51 = Dictionary<Shape>[123];
declare type Q52 = Dictionary<Shape>[E.B];
declare let cond: boolean;
declare function getProperty<T, K extends keyof T>(obj: T, key: K): T[K];
declare function setProperty<T, K extends keyof T>(obj: T, key: K, value: T[K]): void;
declare function f10(shape: Shape): void;
declare function f11(a: Shape[]): void;
declare function f12(t: [Shape, boolean]): void;
declare function f13(foo: any, bar: any): void;
declare class Component<PropType> {
props: PropType;
getProperty<K extends keyof PropType>(key: K): PropType[K];
setProperty<K extends keyof PropType>(key: K, value: PropType[K]): void;
}
declare function f20(component: Component<Shape>): void;
declare function pluck<T, K extends keyof T>(array: T[], key: K): T[K][];
declare function f30(shapes: Shape[]): void;
declare function f31<K extends keyof Shape>(key: K): Shape[K];
declare function f32<K extends "width" | "height">(key: K): Shape[K];
declare class C {
x: string;
protected y: string;
private z;
}
declare function f40(c: C): void;

View file

@ -0,0 +1,577 @@
=== tests/cases/conformance/types/keyof/keyofAndIndexedAccess.ts ===
class Shape {
>Shape : Symbol(Shape, Decl(keyofAndIndexedAccess.ts, 0, 0))
name: string;
>name : Symbol(Shape.name, Decl(keyofAndIndexedAccess.ts, 1, 13))
width: number;
>width : Symbol(Shape.width, Decl(keyofAndIndexedAccess.ts, 2, 17))
height: number;
>height : Symbol(Shape.height, Decl(keyofAndIndexedAccess.ts, 3, 18))
visible: boolean;
>visible : Symbol(Shape.visible, Decl(keyofAndIndexedAccess.ts, 4, 19))
}
class Item {
>Item : Symbol(Item, Decl(keyofAndIndexedAccess.ts, 6, 1))
name: string;
>name : Symbol(Item.name, Decl(keyofAndIndexedAccess.ts, 8, 12))
price: number;
>price : Symbol(Item.price, Decl(keyofAndIndexedAccess.ts, 9, 17))
}
class Options {
>Options : Symbol(Options, Decl(keyofAndIndexedAccess.ts, 11, 1))
visible: "yes" | "no";
>visible : Symbol(Options.visible, Decl(keyofAndIndexedAccess.ts, 13, 15))
}
type Dictionary<T> = { [x: string]: T };
>Dictionary : Symbol(Dictionary, Decl(keyofAndIndexedAccess.ts, 15, 1))
>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 17, 16))
>x : Symbol(x, Decl(keyofAndIndexedAccess.ts, 17, 24))
>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 17, 16))
const enum E { A, B, C }
>E : Symbol(E, Decl(keyofAndIndexedAccess.ts, 17, 40))
>A : Symbol(E.A, Decl(keyofAndIndexedAccess.ts, 19, 14))
>B : Symbol(E.B, Decl(keyofAndIndexedAccess.ts, 19, 17))
>C : Symbol(E.C, Decl(keyofAndIndexedAccess.ts, 19, 20))
type K00 = keyof any; // string | number
>K00 : Symbol(K00, Decl(keyofAndIndexedAccess.ts, 19, 24))
type K01 = keyof string; // number | "toString" | "charAt" | ...
>K01 : Symbol(K01, Decl(keyofAndIndexedAccess.ts, 21, 21))
type K02 = keyof number; // "toString" | "toFixed" | "toExponential" | ...
>K02 : Symbol(K02, Decl(keyofAndIndexedAccess.ts, 22, 24))
type K03 = keyof boolean; // "valueOf"
>K03 : Symbol(K03, Decl(keyofAndIndexedAccess.ts, 23, 24))
type K04 = keyof void; // never
>K04 : Symbol(K04, Decl(keyofAndIndexedAccess.ts, 24, 25))
type K05 = keyof undefined; // never
>K05 : Symbol(K05, Decl(keyofAndIndexedAccess.ts, 25, 22))
type K06 = keyof null; // never
>K06 : Symbol(K06, Decl(keyofAndIndexedAccess.ts, 26, 27))
type K07 = keyof never; // never
>K07 : Symbol(K07, Decl(keyofAndIndexedAccess.ts, 27, 22))
type K10 = keyof Shape; // "name" | "width" | "height" | "visible"
>K10 : Symbol(K10, Decl(keyofAndIndexedAccess.ts, 28, 23))
>Shape : Symbol(Shape, Decl(keyofAndIndexedAccess.ts, 0, 0))
type K11 = keyof Shape[]; // number | "length" | "toString" | ...
>K11 : Symbol(K11, Decl(keyofAndIndexedAccess.ts, 30, 23))
>Shape : Symbol(Shape, Decl(keyofAndIndexedAccess.ts, 0, 0))
type K12 = keyof Dictionary<Shape>; // string | number
>K12 : Symbol(K12, Decl(keyofAndIndexedAccess.ts, 31, 25))
>Dictionary : Symbol(Dictionary, Decl(keyofAndIndexedAccess.ts, 15, 1))
>Shape : Symbol(Shape, Decl(keyofAndIndexedAccess.ts, 0, 0))
type K13 = keyof {}; // never
>K13 : Symbol(K13, Decl(keyofAndIndexedAccess.ts, 32, 35))
type K14 = keyof Object; // "constructor" | "toString" | ...
>K14 : Symbol(K14, Decl(keyofAndIndexedAccess.ts, 33, 20))
>Object : Symbol(Object, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
type K15 = keyof E; // "toString" | "toFixed" | "toExponential" | ...
>K15 : Symbol(K15, Decl(keyofAndIndexedAccess.ts, 34, 24))
>E : Symbol(E, Decl(keyofAndIndexedAccess.ts, 17, 40))
type K16 = keyof [string, number]; // number | "0" | "1" | "length" | "toString" | ...
>K16 : Symbol(K16, Decl(keyofAndIndexedAccess.ts, 35, 19))
type K17 = keyof (Shape | Item); // "name"
>K17 : Symbol(K17, Decl(keyofAndIndexedAccess.ts, 36, 34))
>Shape : Symbol(Shape, Decl(keyofAndIndexedAccess.ts, 0, 0))
>Item : Symbol(Item, Decl(keyofAndIndexedAccess.ts, 6, 1))
type K18 = keyof (Shape & Item); // "name" | "width" | "height" | "visible" | "price"
>K18 : Symbol(K18, Decl(keyofAndIndexedAccess.ts, 37, 32))
>Shape : Symbol(Shape, Decl(keyofAndIndexedAccess.ts, 0, 0))
>Item : Symbol(Item, Decl(keyofAndIndexedAccess.ts, 6, 1))
type KeyOf<T> = keyof T;
>KeyOf : Symbol(KeyOf, Decl(keyofAndIndexedAccess.ts, 38, 32))
>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 40, 11))
>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 40, 11))
type K20 = KeyOf<Shape>; // "name" | "width" | "height" | "visible"
>K20 : Symbol(K20, Decl(keyofAndIndexedAccess.ts, 40, 24))
>KeyOf : Symbol(KeyOf, Decl(keyofAndIndexedAccess.ts, 38, 32))
>Shape : Symbol(Shape, Decl(keyofAndIndexedAccess.ts, 0, 0))
type K21 = KeyOf<Dictionary<Shape>>; // string | number
>K21 : Symbol(K21, Decl(keyofAndIndexedAccess.ts, 42, 24))
>KeyOf : Symbol(KeyOf, Decl(keyofAndIndexedAccess.ts, 38, 32))
>Dictionary : Symbol(Dictionary, Decl(keyofAndIndexedAccess.ts, 15, 1))
>Shape : Symbol(Shape, Decl(keyofAndIndexedAccess.ts, 0, 0))
type NAME = "name";
>NAME : Symbol(NAME, Decl(keyofAndIndexedAccess.ts, 43, 36))
type WIDTH_OR_HEIGHT = "width" | "height";
>WIDTH_OR_HEIGHT : Symbol(WIDTH_OR_HEIGHT, Decl(keyofAndIndexedAccess.ts, 45, 19))
type Q10 = Shape["name"]; // string
>Q10 : Symbol(Q10, Decl(keyofAndIndexedAccess.ts, 46, 42))
>Shape : Symbol(Shape, Decl(keyofAndIndexedAccess.ts, 0, 0))
type Q11 = Shape["width" | "height"]; // number
>Q11 : Symbol(Q11, Decl(keyofAndIndexedAccess.ts, 48, 25))
>Shape : Symbol(Shape, Decl(keyofAndIndexedAccess.ts, 0, 0))
type Q12 = Shape["name" | "visible"]; // string | boolean
>Q12 : Symbol(Q12, Decl(keyofAndIndexedAccess.ts, 49, 37))
>Shape : Symbol(Shape, Decl(keyofAndIndexedAccess.ts, 0, 0))
type Q20 = Shape[NAME]; // string
>Q20 : Symbol(Q20, Decl(keyofAndIndexedAccess.ts, 50, 37))
>Shape : Symbol(Shape, Decl(keyofAndIndexedAccess.ts, 0, 0))
>NAME : Symbol(NAME, Decl(keyofAndIndexedAccess.ts, 43, 36))
type Q21 = Shape[WIDTH_OR_HEIGHT]; // number
>Q21 : Symbol(Q21, Decl(keyofAndIndexedAccess.ts, 52, 23))
>Shape : Symbol(Shape, Decl(keyofAndIndexedAccess.ts, 0, 0))
>WIDTH_OR_HEIGHT : Symbol(WIDTH_OR_HEIGHT, Decl(keyofAndIndexedAccess.ts, 45, 19))
type Q30 = [string, number][0]; // string
>Q30 : Symbol(Q30, Decl(keyofAndIndexedAccess.ts, 53, 34))
type Q31 = [string, number][1]; // number
>Q31 : Symbol(Q31, Decl(keyofAndIndexedAccess.ts, 55, 31))
type Q32 = [string, number][2]; // string | number
>Q32 : Symbol(Q32, Decl(keyofAndIndexedAccess.ts, 56, 31))
type Q33 = [string, number][E.A]; // string
>Q33 : Symbol(Q33, Decl(keyofAndIndexedAccess.ts, 57, 31))
>E : Symbol(E, Decl(keyofAndIndexedAccess.ts, 17, 40))
>A : Symbol(E.A, Decl(keyofAndIndexedAccess.ts, 19, 14))
type Q34 = [string, number][E.B]; // number
>Q34 : Symbol(Q34, Decl(keyofAndIndexedAccess.ts, 58, 33))
>E : Symbol(E, Decl(keyofAndIndexedAccess.ts, 17, 40))
>B : Symbol(E.B, Decl(keyofAndIndexedAccess.ts, 19, 17))
type Q35 = [string, number][E.C]; // string | number
>Q35 : Symbol(Q35, Decl(keyofAndIndexedAccess.ts, 59, 33))
>E : Symbol(E, Decl(keyofAndIndexedAccess.ts, 17, 40))
>C : Symbol(E.C, Decl(keyofAndIndexedAccess.ts, 19, 20))
type Q36 = [string, number]["0"]; // string
>Q36 : Symbol(Q36, Decl(keyofAndIndexedAccess.ts, 60, 33))
type Q37 = [string, number]["1"]; // string
>Q37 : Symbol(Q37, Decl(keyofAndIndexedAccess.ts, 61, 33))
type Q40 = (Shape | Options)["visible"]; // boolean | "yes" | "no"
>Q40 : Symbol(Q40, Decl(keyofAndIndexedAccess.ts, 62, 33))
>Shape : Symbol(Shape, Decl(keyofAndIndexedAccess.ts, 0, 0))
>Options : Symbol(Options, Decl(keyofAndIndexedAccess.ts, 11, 1))
type Q41 = (Shape & Options)["visible"]; // true & "yes" | true & "no" | false & "yes" | false & "no"
>Q41 : Symbol(Q41, Decl(keyofAndIndexedAccess.ts, 64, 40))
>Shape : Symbol(Shape, Decl(keyofAndIndexedAccess.ts, 0, 0))
>Options : Symbol(Options, Decl(keyofAndIndexedAccess.ts, 11, 1))
type Q50 = Dictionary<Shape>["howdy"]; // Shape
>Q50 : Symbol(Q50, Decl(keyofAndIndexedAccess.ts, 65, 40))
>Dictionary : Symbol(Dictionary, Decl(keyofAndIndexedAccess.ts, 15, 1))
>Shape : Symbol(Shape, Decl(keyofAndIndexedAccess.ts, 0, 0))
type Q51 = Dictionary<Shape>[123]; // Shape
>Q51 : Symbol(Q51, Decl(keyofAndIndexedAccess.ts, 67, 38))
>Dictionary : Symbol(Dictionary, Decl(keyofAndIndexedAccess.ts, 15, 1))
>Shape : Symbol(Shape, Decl(keyofAndIndexedAccess.ts, 0, 0))
type Q52 = Dictionary<Shape>[E.B]; // Shape
>Q52 : Symbol(Q52, Decl(keyofAndIndexedAccess.ts, 68, 34))
>Dictionary : Symbol(Dictionary, Decl(keyofAndIndexedAccess.ts, 15, 1))
>Shape : Symbol(Shape, Decl(keyofAndIndexedAccess.ts, 0, 0))
>E : Symbol(E, Decl(keyofAndIndexedAccess.ts, 17, 40))
>B : Symbol(E.B, Decl(keyofAndIndexedAccess.ts, 19, 17))
declare let cond: boolean;
>cond : Symbol(cond, Decl(keyofAndIndexedAccess.ts, 71, 11))
function getProperty<T, K extends keyof T>(obj: T, key: K) {
>getProperty : Symbol(getProperty, Decl(keyofAndIndexedAccess.ts, 71, 26))
>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 73, 21))
>K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 73, 23))
>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 73, 21))
>obj : Symbol(obj, Decl(keyofAndIndexedAccess.ts, 73, 43))
>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 73, 21))
>key : Symbol(key, Decl(keyofAndIndexedAccess.ts, 73, 50))
>K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 73, 23))
return obj[key];
>obj : Symbol(obj, Decl(keyofAndIndexedAccess.ts, 73, 43))
>key : Symbol(key, Decl(keyofAndIndexedAccess.ts, 73, 50))
}
function setProperty<T, K extends keyof T>(obj: T, key: K, value: T[K]) {
>setProperty : Symbol(setProperty, Decl(keyofAndIndexedAccess.ts, 75, 1))
>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 77, 21))
>K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 77, 23))
>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 77, 21))
>obj : Symbol(obj, Decl(keyofAndIndexedAccess.ts, 77, 43))
>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 77, 21))
>key : Symbol(key, Decl(keyofAndIndexedAccess.ts, 77, 50))
>K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 77, 23))
>value : Symbol(value, Decl(keyofAndIndexedAccess.ts, 77, 58))
>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 77, 21))
>K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 77, 23))
obj[key] = value;
>obj : Symbol(obj, Decl(keyofAndIndexedAccess.ts, 77, 43))
>key : Symbol(key, Decl(keyofAndIndexedAccess.ts, 77, 50))
>value : Symbol(value, Decl(keyofAndIndexedAccess.ts, 77, 58))
}
function f10(shape: Shape) {
>f10 : Symbol(f10, Decl(keyofAndIndexedAccess.ts, 79, 1))
>shape : Symbol(shape, Decl(keyofAndIndexedAccess.ts, 81, 13))
>Shape : Symbol(Shape, Decl(keyofAndIndexedAccess.ts, 0, 0))
let name = getProperty(shape, "name"); // string
>name : Symbol(name, Decl(keyofAndIndexedAccess.ts, 82, 7))
>getProperty : Symbol(getProperty, Decl(keyofAndIndexedAccess.ts, 71, 26))
>shape : Symbol(shape, Decl(keyofAndIndexedAccess.ts, 81, 13))
let widthOrHeight = getProperty(shape, cond ? "width" : "height"); // number
>widthOrHeight : Symbol(widthOrHeight, Decl(keyofAndIndexedAccess.ts, 83, 7))
>getProperty : Symbol(getProperty, Decl(keyofAndIndexedAccess.ts, 71, 26))
>shape : Symbol(shape, Decl(keyofAndIndexedAccess.ts, 81, 13))
>cond : Symbol(cond, Decl(keyofAndIndexedAccess.ts, 71, 11))
let nameOrVisible = getProperty(shape, cond ? "name" : "visible"); // string | boolean
>nameOrVisible : Symbol(nameOrVisible, Decl(keyofAndIndexedAccess.ts, 84, 7))
>getProperty : Symbol(getProperty, Decl(keyofAndIndexedAccess.ts, 71, 26))
>shape : Symbol(shape, Decl(keyofAndIndexedAccess.ts, 81, 13))
>cond : Symbol(cond, Decl(keyofAndIndexedAccess.ts, 71, 11))
setProperty(shape, "name", "rectangle");
>setProperty : Symbol(setProperty, Decl(keyofAndIndexedAccess.ts, 75, 1))
>shape : Symbol(shape, Decl(keyofAndIndexedAccess.ts, 81, 13))
setProperty(shape, cond ? "width" : "height", 10);
>setProperty : Symbol(setProperty, Decl(keyofAndIndexedAccess.ts, 75, 1))
>shape : Symbol(shape, Decl(keyofAndIndexedAccess.ts, 81, 13))
>cond : Symbol(cond, Decl(keyofAndIndexedAccess.ts, 71, 11))
setProperty(shape, cond ? "name" : "visible", true); // Technically not safe
>setProperty : Symbol(setProperty, Decl(keyofAndIndexedAccess.ts, 75, 1))
>shape : Symbol(shape, Decl(keyofAndIndexedAccess.ts, 81, 13))
>cond : Symbol(cond, Decl(keyofAndIndexedAccess.ts, 71, 11))
}
function f11(a: Shape[]) {
>f11 : Symbol(f11, Decl(keyofAndIndexedAccess.ts, 88, 1))
>a : Symbol(a, Decl(keyofAndIndexedAccess.ts, 90, 13))
>Shape : Symbol(Shape, Decl(keyofAndIndexedAccess.ts, 0, 0))
let len = getProperty(a, "length"); // number
>len : Symbol(len, Decl(keyofAndIndexedAccess.ts, 91, 7))
>getProperty : Symbol(getProperty, Decl(keyofAndIndexedAccess.ts, 71, 26))
>a : Symbol(a, Decl(keyofAndIndexedAccess.ts, 90, 13))
let shape = getProperty(a, 1000); // Shape
>shape : Symbol(shape, Decl(keyofAndIndexedAccess.ts, 92, 7))
>getProperty : Symbol(getProperty, Decl(keyofAndIndexedAccess.ts, 71, 26))
>a : Symbol(a, Decl(keyofAndIndexedAccess.ts, 90, 13))
setProperty(a, 1000, getProperty(a, 1001));
>setProperty : Symbol(setProperty, Decl(keyofAndIndexedAccess.ts, 75, 1))
>a : Symbol(a, Decl(keyofAndIndexedAccess.ts, 90, 13))
>getProperty : Symbol(getProperty, Decl(keyofAndIndexedAccess.ts, 71, 26))
>a : Symbol(a, Decl(keyofAndIndexedAccess.ts, 90, 13))
}
function f12(t: [Shape, boolean]) {
>f12 : Symbol(f12, Decl(keyofAndIndexedAccess.ts, 94, 1))
>t : Symbol(t, Decl(keyofAndIndexedAccess.ts, 96, 13))
>Shape : Symbol(Shape, Decl(keyofAndIndexedAccess.ts, 0, 0))
let len = getProperty(t, "length");
>len : Symbol(len, Decl(keyofAndIndexedAccess.ts, 97, 7))
>getProperty : Symbol(getProperty, Decl(keyofAndIndexedAccess.ts, 71, 26))
>t : Symbol(t, Decl(keyofAndIndexedAccess.ts, 96, 13))
let s1 = getProperty(t, 0); // Shape
>s1 : Symbol(s1, Decl(keyofAndIndexedAccess.ts, 98, 7))
>getProperty : Symbol(getProperty, Decl(keyofAndIndexedAccess.ts, 71, 26))
>t : Symbol(t, Decl(keyofAndIndexedAccess.ts, 96, 13))
let s2 = getProperty(t, "0"); // Shape
>s2 : Symbol(s2, Decl(keyofAndIndexedAccess.ts, 99, 7))
>getProperty : Symbol(getProperty, Decl(keyofAndIndexedAccess.ts, 71, 26))
>t : Symbol(t, Decl(keyofAndIndexedAccess.ts, 96, 13))
let b1 = getProperty(t, 1); // boolean
>b1 : Symbol(b1, Decl(keyofAndIndexedAccess.ts, 100, 7))
>getProperty : Symbol(getProperty, Decl(keyofAndIndexedAccess.ts, 71, 26))
>t : Symbol(t, Decl(keyofAndIndexedAccess.ts, 96, 13))
let b2 = getProperty(t, "1"); // boolean
>b2 : Symbol(b2, Decl(keyofAndIndexedAccess.ts, 101, 7))
>getProperty : Symbol(getProperty, Decl(keyofAndIndexedAccess.ts, 71, 26))
>t : Symbol(t, Decl(keyofAndIndexedAccess.ts, 96, 13))
let x1 = getProperty(t, 2); // Shape | boolean
>x1 : Symbol(x1, Decl(keyofAndIndexedAccess.ts, 102, 7))
>getProperty : Symbol(getProperty, Decl(keyofAndIndexedAccess.ts, 71, 26))
>t : Symbol(t, Decl(keyofAndIndexedAccess.ts, 96, 13))
}
function f13(foo: any, bar: any) {
>f13 : Symbol(f13, Decl(keyofAndIndexedAccess.ts, 103, 1))
>foo : Symbol(foo, Decl(keyofAndIndexedAccess.ts, 105, 13))
>bar : Symbol(bar, Decl(keyofAndIndexedAccess.ts, 105, 22))
let x = getProperty(foo, "x"); // any
>x : Symbol(x, Decl(keyofAndIndexedAccess.ts, 106, 7))
>getProperty : Symbol(getProperty, Decl(keyofAndIndexedAccess.ts, 71, 26))
>foo : Symbol(foo, Decl(keyofAndIndexedAccess.ts, 105, 13))
let y = getProperty(foo, 100); // any
>y : Symbol(y, Decl(keyofAndIndexedAccess.ts, 107, 7))
>getProperty : Symbol(getProperty, Decl(keyofAndIndexedAccess.ts, 71, 26))
>foo : Symbol(foo, Decl(keyofAndIndexedAccess.ts, 105, 13))
let z = getProperty(foo, bar); // any
>z : Symbol(z, Decl(keyofAndIndexedAccess.ts, 108, 7))
>getProperty : Symbol(getProperty, Decl(keyofAndIndexedAccess.ts, 71, 26))
>foo : Symbol(foo, Decl(keyofAndIndexedAccess.ts, 105, 13))
>bar : Symbol(bar, Decl(keyofAndIndexedAccess.ts, 105, 22))
}
class Component<PropType> {
>Component : Symbol(Component, Decl(keyofAndIndexedAccess.ts, 109, 1))
>PropType : Symbol(PropType, Decl(keyofAndIndexedAccess.ts, 111, 16))
props: PropType;
>props : Symbol(Component.props, Decl(keyofAndIndexedAccess.ts, 111, 27))
>PropType : Symbol(PropType, Decl(keyofAndIndexedAccess.ts, 111, 16))
getProperty<K extends keyof PropType>(key: K) {
>getProperty : Symbol(Component.getProperty, Decl(keyofAndIndexedAccess.ts, 112, 20))
>K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 113, 16))
>PropType : Symbol(PropType, Decl(keyofAndIndexedAccess.ts, 111, 16))
>key : Symbol(key, Decl(keyofAndIndexedAccess.ts, 113, 42))
>K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 113, 16))
return this.props[key];
>this.props : Symbol(Component.props, Decl(keyofAndIndexedAccess.ts, 111, 27))
>this : Symbol(Component, Decl(keyofAndIndexedAccess.ts, 109, 1))
>props : Symbol(Component.props, Decl(keyofAndIndexedAccess.ts, 111, 27))
>key : Symbol(key, Decl(keyofAndIndexedAccess.ts, 113, 42))
}
setProperty<K extends keyof PropType>(key: K, value: PropType[K]) {
>setProperty : Symbol(Component.setProperty, Decl(keyofAndIndexedAccess.ts, 115, 5))
>K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 116, 16))
>PropType : Symbol(PropType, Decl(keyofAndIndexedAccess.ts, 111, 16))
>key : Symbol(key, Decl(keyofAndIndexedAccess.ts, 116, 42))
>K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 116, 16))
>value : Symbol(value, Decl(keyofAndIndexedAccess.ts, 116, 49))
>PropType : Symbol(PropType, Decl(keyofAndIndexedAccess.ts, 111, 16))
>K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 116, 16))
this.props[key] = value;
>this.props : Symbol(Component.props, Decl(keyofAndIndexedAccess.ts, 111, 27))
>this : Symbol(Component, Decl(keyofAndIndexedAccess.ts, 109, 1))
>props : Symbol(Component.props, Decl(keyofAndIndexedAccess.ts, 111, 27))
>key : Symbol(key, Decl(keyofAndIndexedAccess.ts, 116, 42))
>value : Symbol(value, Decl(keyofAndIndexedAccess.ts, 116, 49))
}
}
function f20(component: Component<Shape>) {
>f20 : Symbol(f20, Decl(keyofAndIndexedAccess.ts, 119, 1))
>component : Symbol(component, Decl(keyofAndIndexedAccess.ts, 121, 13))
>Component : Symbol(Component, Decl(keyofAndIndexedAccess.ts, 109, 1))
>Shape : Symbol(Shape, Decl(keyofAndIndexedAccess.ts, 0, 0))
let name = component.getProperty("name"); // string
>name : Symbol(name, Decl(keyofAndIndexedAccess.ts, 122, 7))
>component.getProperty : Symbol(Component.getProperty, Decl(keyofAndIndexedAccess.ts, 112, 20))
>component : Symbol(component, Decl(keyofAndIndexedAccess.ts, 121, 13))
>getProperty : Symbol(Component.getProperty, Decl(keyofAndIndexedAccess.ts, 112, 20))
let widthOrHeight = component.getProperty(cond ? "width" : "height"); // number
>widthOrHeight : Symbol(widthOrHeight, Decl(keyofAndIndexedAccess.ts, 123, 7))
>component.getProperty : Symbol(Component.getProperty, Decl(keyofAndIndexedAccess.ts, 112, 20))
>component : Symbol(component, Decl(keyofAndIndexedAccess.ts, 121, 13))
>getProperty : Symbol(Component.getProperty, Decl(keyofAndIndexedAccess.ts, 112, 20))
>cond : Symbol(cond, Decl(keyofAndIndexedAccess.ts, 71, 11))
let nameOrVisible = component.getProperty(cond ? "name" : "visible"); // string | boolean
>nameOrVisible : Symbol(nameOrVisible, Decl(keyofAndIndexedAccess.ts, 124, 7))
>component.getProperty : Symbol(Component.getProperty, Decl(keyofAndIndexedAccess.ts, 112, 20))
>component : Symbol(component, Decl(keyofAndIndexedAccess.ts, 121, 13))
>getProperty : Symbol(Component.getProperty, Decl(keyofAndIndexedAccess.ts, 112, 20))
>cond : Symbol(cond, Decl(keyofAndIndexedAccess.ts, 71, 11))
component.setProperty("name", "rectangle");
>component.setProperty : Symbol(Component.setProperty, Decl(keyofAndIndexedAccess.ts, 115, 5))
>component : Symbol(component, Decl(keyofAndIndexedAccess.ts, 121, 13))
>setProperty : Symbol(Component.setProperty, Decl(keyofAndIndexedAccess.ts, 115, 5))
component.setProperty(cond ? "width" : "height", 10)
>component.setProperty : Symbol(Component.setProperty, Decl(keyofAndIndexedAccess.ts, 115, 5))
>component : Symbol(component, Decl(keyofAndIndexedAccess.ts, 121, 13))
>setProperty : Symbol(Component.setProperty, Decl(keyofAndIndexedAccess.ts, 115, 5))
>cond : Symbol(cond, Decl(keyofAndIndexedAccess.ts, 71, 11))
component.setProperty(cond ? "name" : "visible", true); // Technically not safe
>component.setProperty : Symbol(Component.setProperty, Decl(keyofAndIndexedAccess.ts, 115, 5))
>component : Symbol(component, Decl(keyofAndIndexedAccess.ts, 121, 13))
>setProperty : Symbol(Component.setProperty, Decl(keyofAndIndexedAccess.ts, 115, 5))
>cond : Symbol(cond, Decl(keyofAndIndexedAccess.ts, 71, 11))
}
function pluck<T, K extends keyof T>(array: T[], key: K) {
>pluck : Symbol(pluck, Decl(keyofAndIndexedAccess.ts, 128, 1))
>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 130, 15))
>K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 130, 17))
>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 130, 15))
>array : Symbol(array, Decl(keyofAndIndexedAccess.ts, 130, 37))
>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 130, 15))
>key : Symbol(key, Decl(keyofAndIndexedAccess.ts, 130, 48))
>K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 130, 17))
return array.map(x => x[key]);
>array.map : Symbol(Array.map, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
>array : Symbol(array, Decl(keyofAndIndexedAccess.ts, 130, 37))
>map : Symbol(Array.map, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
>x : Symbol(x, Decl(keyofAndIndexedAccess.ts, 131, 21))
>x : Symbol(x, Decl(keyofAndIndexedAccess.ts, 131, 21))
>key : Symbol(key, Decl(keyofAndIndexedAccess.ts, 130, 48))
}
function f30(shapes: Shape[]) {
>f30 : Symbol(f30, Decl(keyofAndIndexedAccess.ts, 132, 1))
>shapes : Symbol(shapes, Decl(keyofAndIndexedAccess.ts, 134, 13))
>Shape : Symbol(Shape, Decl(keyofAndIndexedAccess.ts, 0, 0))
let names = pluck(shapes, "name"); // string[]
>names : Symbol(names, Decl(keyofAndIndexedAccess.ts, 135, 7))
>pluck : Symbol(pluck, Decl(keyofAndIndexedAccess.ts, 128, 1))
>shapes : Symbol(shapes, Decl(keyofAndIndexedAccess.ts, 134, 13))
let widths = pluck(shapes, "width"); // number[]
>widths : Symbol(widths, Decl(keyofAndIndexedAccess.ts, 136, 7))
>pluck : Symbol(pluck, Decl(keyofAndIndexedAccess.ts, 128, 1))
>shapes : Symbol(shapes, Decl(keyofAndIndexedAccess.ts, 134, 13))
let nameOrVisibles = pluck(shapes, cond ? "name" : "visible"); // (string | boolean)[]
>nameOrVisibles : Symbol(nameOrVisibles, Decl(keyofAndIndexedAccess.ts, 137, 7))
>pluck : Symbol(pluck, Decl(keyofAndIndexedAccess.ts, 128, 1))
>shapes : Symbol(shapes, Decl(keyofAndIndexedAccess.ts, 134, 13))
>cond : Symbol(cond, Decl(keyofAndIndexedAccess.ts, 71, 11))
}
function f31<K extends keyof Shape>(key: K) {
>f31 : Symbol(f31, Decl(keyofAndIndexedAccess.ts, 138, 1))
>K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 140, 13))
>Shape : Symbol(Shape, Decl(keyofAndIndexedAccess.ts, 0, 0))
>key : Symbol(key, Decl(keyofAndIndexedAccess.ts, 140, 36))
>K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 140, 13))
const shape: Shape = { name: "foo", width: 5, height: 10, visible: true };
>shape : Symbol(shape, Decl(keyofAndIndexedAccess.ts, 141, 9))
>Shape : Symbol(Shape, Decl(keyofAndIndexedAccess.ts, 0, 0))
>name : Symbol(name, Decl(keyofAndIndexedAccess.ts, 141, 26))
>width : Symbol(width, Decl(keyofAndIndexedAccess.ts, 141, 39))
>height : Symbol(height, Decl(keyofAndIndexedAccess.ts, 141, 49))
>visible : Symbol(visible, Decl(keyofAndIndexedAccess.ts, 141, 61))
return shape[key]; // Shape[K]
>shape : Symbol(shape, Decl(keyofAndIndexedAccess.ts, 141, 9))
>key : Symbol(key, Decl(keyofAndIndexedAccess.ts, 140, 36))
}
function f32<K extends "width" | "height">(key: K) {
>f32 : Symbol(f32, Decl(keyofAndIndexedAccess.ts, 143, 1))
>K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 145, 13))
>key : Symbol(key, Decl(keyofAndIndexedAccess.ts, 145, 43))
>K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 145, 13))
const shape: Shape = { name: "foo", width: 5, height: 10, visible: true };
>shape : Symbol(shape, Decl(keyofAndIndexedAccess.ts, 146, 9))
>Shape : Symbol(Shape, Decl(keyofAndIndexedAccess.ts, 0, 0))
>name : Symbol(name, Decl(keyofAndIndexedAccess.ts, 146, 26))
>width : Symbol(width, Decl(keyofAndIndexedAccess.ts, 146, 39))
>height : Symbol(height, Decl(keyofAndIndexedAccess.ts, 146, 49))
>visible : Symbol(visible, Decl(keyofAndIndexedAccess.ts, 146, 61))
return shape[key]; // Shape[K]
>shape : Symbol(shape, Decl(keyofAndIndexedAccess.ts, 146, 9))
>key : Symbol(key, Decl(keyofAndIndexedAccess.ts, 145, 43))
}
class C {
>C : Symbol(C, Decl(keyofAndIndexedAccess.ts, 148, 1))
public x: string;
>x : Symbol(C.x, Decl(keyofAndIndexedAccess.ts, 150, 9))
protected y: string;
>y : Symbol(C.y, Decl(keyofAndIndexedAccess.ts, 151, 21))
private z: string;
>z : Symbol(C.z, Decl(keyofAndIndexedAccess.ts, 152, 24))
}
// Indexed access expressions have always permitted access to private and protected members.
// For consistency we also permit such access in indexed access types.
function f40(c: C) {
>f40 : Symbol(f40, Decl(keyofAndIndexedAccess.ts, 154, 1))
>c : Symbol(c, Decl(keyofAndIndexedAccess.ts, 158, 13))
>C : Symbol(C, Decl(keyofAndIndexedAccess.ts, 148, 1))
type X = C["x"];
>X : Symbol(X, Decl(keyofAndIndexedAccess.ts, 158, 20))
>C : Symbol(C, Decl(keyofAndIndexedAccess.ts, 148, 1))
type Y = C["y"];
>Y : Symbol(Y, Decl(keyofAndIndexedAccess.ts, 159, 20))
>C : Symbol(C, Decl(keyofAndIndexedAccess.ts, 148, 1))
type Z = C["z"];
>Z : Symbol(Z, Decl(keyofAndIndexedAccess.ts, 160, 20))
>C : Symbol(C, Decl(keyofAndIndexedAccess.ts, 148, 1))
let x: X = c["x"];
>x : Symbol(x, Decl(keyofAndIndexedAccess.ts, 162, 7))
>X : Symbol(X, Decl(keyofAndIndexedAccess.ts, 158, 20))
>c : Symbol(c, Decl(keyofAndIndexedAccess.ts, 158, 13))
>"x" : Symbol(C.x, Decl(keyofAndIndexedAccess.ts, 150, 9))
let y: Y = c["y"];
>y : Symbol(y, Decl(keyofAndIndexedAccess.ts, 163, 7))
>Y : Symbol(Y, Decl(keyofAndIndexedAccess.ts, 159, 20))
>c : Symbol(c, Decl(keyofAndIndexedAccess.ts, 158, 13))
>"y" : Symbol(C.y, Decl(keyofAndIndexedAccess.ts, 151, 21))
let z: Z = c["z"];
>z : Symbol(z, Decl(keyofAndIndexedAccess.ts, 164, 7))
>Z : Symbol(Z, Decl(keyofAndIndexedAccess.ts, 160, 20))
>c : Symbol(c, Decl(keyofAndIndexedAccess.ts, 158, 13))
>"z" : Symbol(C.z, Decl(keyofAndIndexedAccess.ts, 152, 24))
}

View file

@ -0,0 +1,681 @@
=== tests/cases/conformance/types/keyof/keyofAndIndexedAccess.ts ===
class Shape {
>Shape : Shape
name: string;
>name : string
width: number;
>width : number
height: number;
>height : number
visible: boolean;
>visible : boolean
}
class Item {
>Item : Item
name: string;
>name : string
price: number;
>price : number
}
class Options {
>Options : Options
visible: "yes" | "no";
>visible : "yes" | "no"
}
type Dictionary<T> = { [x: string]: T };
>Dictionary : { [x: string]: T; }
>T : T
>x : string
>T : T
const enum E { A, B, C }
>E : E
>A : E.A
>B : E.B
>C : E.C
type K00 = keyof any; // string | number
>K00 : string | number
type K01 = keyof string; // number | "toString" | "charAt" | ...
>K01 : number | "length" | "toString" | "concat" | "slice" | "indexOf" | "lastIndexOf" | "charAt" | "charCodeAt" | "localeCompare" | "match" | "replace" | "search" | "split" | "substring" | "toLowerCase" | "toLocaleLowerCase" | "toUpperCase" | "toLocaleUpperCase" | "trim" | "substr" | "valueOf"
type K02 = keyof number; // "toString" | "toFixed" | "toExponential" | ...
>K02 : "toString" | "toLocaleString" | "valueOf" | "toFixed" | "toExponential" | "toPrecision"
type K03 = keyof boolean; // "valueOf"
>K03 : "valueOf"
type K04 = keyof void; // never
>K04 : never
type K05 = keyof undefined; // never
>K05 : never
type K06 = keyof null; // never
>K06 : never
>null : null
type K07 = keyof never; // never
>K07 : never
type K10 = keyof Shape; // "name" | "width" | "height" | "visible"
>K10 : "name" | "width" | "height" | "visible"
>Shape : Shape
type K11 = keyof Shape[]; // number | "length" | "toString" | ...
>K11 : number | "length" | "toString" | "toLocaleString" | "push" | "pop" | "concat" | "join" | "reverse" | "shift" | "slice" | "sort" | "splice" | "unshift" | "indexOf" | "lastIndexOf" | "every" | "some" | "forEach" | "map" | "filter" | "reduce" | "reduceRight"
>Shape : Shape
type K12 = keyof Dictionary<Shape>; // string | number
>K12 : string | number
>Dictionary : { [x: string]: T; }
>Shape : Shape
type K13 = keyof {}; // never
>K13 : never
type K14 = keyof Object; // "constructor" | "toString" | ...
>K14 : "toString" | "toLocaleString" | "valueOf" | "constructor" | "hasOwnProperty" | "isPrototypeOf" | "propertyIsEnumerable"
>Object : Object
type K15 = keyof E; // "toString" | "toFixed" | "toExponential" | ...
>K15 : "toString" | "toLocaleString" | "valueOf" | "toFixed" | "toExponential" | "toPrecision"
>E : E
type K16 = keyof [string, number]; // number | "0" | "1" | "length" | "toString" | ...
>K16 : number | "0" | "1" | "length" | "toString" | "toLocaleString" | "push" | "pop" | "concat" | "join" | "reverse" | "shift" | "slice" | "sort" | "splice" | "unshift" | "indexOf" | "lastIndexOf" | "every" | "some" | "forEach" | "map" | "filter" | "reduce" | "reduceRight"
type K17 = keyof (Shape | Item); // "name"
>K17 : "name"
>Shape : Shape
>Item : Item
type K18 = keyof (Shape & Item); // "name" | "width" | "height" | "visible" | "price"
>K18 : "name" | "width" | "height" | "visible" | "price"
>Shape : Shape
>Item : Item
type KeyOf<T> = keyof T;
>KeyOf : keyof T
>T : T
>T : T
type K20 = KeyOf<Shape>; // "name" | "width" | "height" | "visible"
>K20 : "name" | "width" | "height" | "visible"
>KeyOf : keyof T
>Shape : Shape
type K21 = KeyOf<Dictionary<Shape>>; // string | number
>K21 : string | number
>KeyOf : keyof T
>Dictionary : { [x: string]: T; }
>Shape : Shape
type NAME = "name";
>NAME : "name"
type WIDTH_OR_HEIGHT = "width" | "height";
>WIDTH_OR_HEIGHT : "width" | "height"
type Q10 = Shape["name"]; // string
>Q10 : string
>Shape : Shape
type Q11 = Shape["width" | "height"]; // number
>Q11 : number
>Shape : Shape
type Q12 = Shape["name" | "visible"]; // string | boolean
>Q12 : string | boolean
>Shape : Shape
type Q20 = Shape[NAME]; // string
>Q20 : string
>Shape : Shape
>NAME : "name"
type Q21 = Shape[WIDTH_OR_HEIGHT]; // number
>Q21 : number
>Shape : Shape
>WIDTH_OR_HEIGHT : "width" | "height"
type Q30 = [string, number][0]; // string
>Q30 : string
type Q31 = [string, number][1]; // number
>Q31 : number
type Q32 = [string, number][2]; // string | number
>Q32 : string | number
type Q33 = [string, number][E.A]; // string
>Q33 : string
>E : any
>A : E.A
type Q34 = [string, number][E.B]; // number
>Q34 : number
>E : any
>B : E.B
type Q35 = [string, number][E.C]; // string | number
>Q35 : string | number
>E : any
>C : E.C
type Q36 = [string, number]["0"]; // string
>Q36 : string
type Q37 = [string, number]["1"]; // string
>Q37 : number
type Q40 = (Shape | Options)["visible"]; // boolean | "yes" | "no"
>Q40 : boolean | "yes" | "no"
>Shape : Shape
>Options : Options
type Q41 = (Shape & Options)["visible"]; // true & "yes" | true & "no" | false & "yes" | false & "no"
>Q41 : (true & "yes") | (true & "no") | (false & "yes") | (false & "no")
>Shape : Shape
>Options : Options
type Q50 = Dictionary<Shape>["howdy"]; // Shape
>Q50 : Shape
>Dictionary : { [x: string]: T; }
>Shape : Shape
type Q51 = Dictionary<Shape>[123]; // Shape
>Q51 : Shape
>Dictionary : { [x: string]: T; }
>Shape : Shape
type Q52 = Dictionary<Shape>[E.B]; // Shape
>Q52 : Shape
>Dictionary : { [x: string]: T; }
>Shape : Shape
>E : any
>B : E.B
declare let cond: boolean;
>cond : boolean
function getProperty<T, K extends keyof T>(obj: T, key: K) {
>getProperty : <T, K extends keyof T>(obj: T, key: K) => T[K]
>T : T
>K : K
>T : T
>obj : T
>T : T
>key : K
>K : K
return obj[key];
>obj[key] : T[K]
>obj : T
>key : K
}
function setProperty<T, K extends keyof T>(obj: T, key: K, value: T[K]) {
>setProperty : <T, K extends keyof T>(obj: T, key: K, value: T[K]) => void
>T : T
>K : K
>T : T
>obj : T
>T : T
>key : K
>K : K
>value : T[K]
>T : T
>K : K
obj[key] = value;
>obj[key] = value : T[K]
>obj[key] : T[K]
>obj : T
>key : K
>value : T[K]
}
function f10(shape: Shape) {
>f10 : (shape: Shape) => void
>shape : Shape
>Shape : Shape
let name = getProperty(shape, "name"); // string
>name : string
>getProperty(shape, "name") : string
>getProperty : <T, K extends keyof T>(obj: T, key: K) => T[K]
>shape : Shape
>"name" : "name"
let widthOrHeight = getProperty(shape, cond ? "width" : "height"); // number
>widthOrHeight : number
>getProperty(shape, cond ? "width" : "height") : number
>getProperty : <T, K extends keyof T>(obj: T, key: K) => T[K]
>shape : Shape
>cond ? "width" : "height" : "width" | "height"
>cond : boolean
>"width" : "width"
>"height" : "height"
let nameOrVisible = getProperty(shape, cond ? "name" : "visible"); // string | boolean
>nameOrVisible : string | boolean
>getProperty(shape, cond ? "name" : "visible") : string | boolean
>getProperty : <T, K extends keyof T>(obj: T, key: K) => T[K]
>shape : Shape
>cond ? "name" : "visible" : "name" | "visible"
>cond : boolean
>"name" : "name"
>"visible" : "visible"
setProperty(shape, "name", "rectangle");
>setProperty(shape, "name", "rectangle") : void
>setProperty : <T, K extends keyof T>(obj: T, key: K, value: T[K]) => void
>shape : Shape
>"name" : "name"
>"rectangle" : "rectangle"
setProperty(shape, cond ? "width" : "height", 10);
>setProperty(shape, cond ? "width" : "height", 10) : void
>setProperty : <T, K extends keyof T>(obj: T, key: K, value: T[K]) => void
>shape : Shape
>cond ? "width" : "height" : "width" | "height"
>cond : boolean
>"width" : "width"
>"height" : "height"
>10 : 10
setProperty(shape, cond ? "name" : "visible", true); // Technically not safe
>setProperty(shape, cond ? "name" : "visible", true) : void
>setProperty : <T, K extends keyof T>(obj: T, key: K, value: T[K]) => void
>shape : Shape
>cond ? "name" : "visible" : "name" | "visible"
>cond : boolean
>"name" : "name"
>"visible" : "visible"
>true : true
}
function f11(a: Shape[]) {
>f11 : (a: Shape[]) => void
>a : Shape[]
>Shape : Shape
let len = getProperty(a, "length"); // number
>len : number
>getProperty(a, "length") : number
>getProperty : <T, K extends keyof T>(obj: T, key: K) => T[K]
>a : Shape[]
>"length" : "length"
let shape = getProperty(a, 1000); // Shape
>shape : Shape
>getProperty(a, 1000) : Shape
>getProperty : <T, K extends keyof T>(obj: T, key: K) => T[K]
>a : Shape[]
>1000 : 1000
setProperty(a, 1000, getProperty(a, 1001));
>setProperty(a, 1000, getProperty(a, 1001)) : void
>setProperty : <T, K extends keyof T>(obj: T, key: K, value: T[K]) => void
>a : Shape[]
>1000 : 1000
>getProperty(a, 1001) : Shape
>getProperty : <T, K extends keyof T>(obj: T, key: K) => T[K]
>a : Shape[]
>1001 : 1001
}
function f12(t: [Shape, boolean]) {
>f12 : (t: [Shape, boolean]) => void
>t : [Shape, boolean]
>Shape : Shape
let len = getProperty(t, "length");
>len : number
>getProperty(t, "length") : number
>getProperty : <T, K extends keyof T>(obj: T, key: K) => T[K]
>t : [Shape, boolean]
>"length" : "length"
let s1 = getProperty(t, 0); // Shape
>s1 : Shape
>getProperty(t, 0) : Shape
>getProperty : <T, K extends keyof T>(obj: T, key: K) => T[K]
>t : [Shape, boolean]
>0 : 0
let s2 = getProperty(t, "0"); // Shape
>s2 : Shape
>getProperty(t, "0") : Shape
>getProperty : <T, K extends keyof T>(obj: T, key: K) => T[K]
>t : [Shape, boolean]
>"0" : "0"
let b1 = getProperty(t, 1); // boolean
>b1 : boolean
>getProperty(t, 1) : boolean
>getProperty : <T, K extends keyof T>(obj: T, key: K) => T[K]
>t : [Shape, boolean]
>1 : 1
let b2 = getProperty(t, "1"); // boolean
>b2 : boolean
>getProperty(t, "1") : boolean
>getProperty : <T, K extends keyof T>(obj: T, key: K) => T[K]
>t : [Shape, boolean]
>"1" : "1"
let x1 = getProperty(t, 2); // Shape | boolean
>x1 : boolean | Shape
>getProperty(t, 2) : boolean | Shape
>getProperty : <T, K extends keyof T>(obj: T, key: K) => T[K]
>t : [Shape, boolean]
>2 : 2
}
function f13(foo: any, bar: any) {
>f13 : (foo: any, bar: any) => void
>foo : any
>bar : any
let x = getProperty(foo, "x"); // any
>x : any
>getProperty(foo, "x") : any
>getProperty : <T, K extends keyof T>(obj: T, key: K) => T[K]
>foo : any
>"x" : "x"
let y = getProperty(foo, 100); // any
>y : any
>getProperty(foo, 100) : any
>getProperty : <T, K extends keyof T>(obj: T, key: K) => T[K]
>foo : any
>100 : 100
let z = getProperty(foo, bar); // any
>z : any
>getProperty(foo, bar) : any
>getProperty : <T, K extends keyof T>(obj: T, key: K) => T[K]
>foo : any
>bar : any
}
class Component<PropType> {
>Component : Component<PropType>
>PropType : PropType
props: PropType;
>props : PropType
>PropType : PropType
getProperty<K extends keyof PropType>(key: K) {
>getProperty : <K extends keyof PropType>(key: K) => PropType[K]
>K : K
>PropType : PropType
>key : K
>K : K
return this.props[key];
>this.props[key] : PropType[K]
>this.props : PropType
>this : this
>props : PropType
>key : K
}
setProperty<K extends keyof PropType>(key: K, value: PropType[K]) {
>setProperty : <K extends keyof PropType>(key: K, value: PropType[K]) => void
>K : K
>PropType : PropType
>key : K
>K : K
>value : PropType[K]
>PropType : PropType
>K : K
this.props[key] = value;
>this.props[key] = value : PropType[K]
>this.props[key] : PropType[K]
>this.props : PropType
>this : this
>props : PropType
>key : K
>value : PropType[K]
}
}
function f20(component: Component<Shape>) {
>f20 : (component: Component<Shape>) => void
>component : Component<Shape>
>Component : Component<PropType>
>Shape : Shape
let name = component.getProperty("name"); // string
>name : string
>component.getProperty("name") : string
>component.getProperty : <K extends "name" | "width" | "height" | "visible">(key: K) => Shape[K]
>component : Component<Shape>
>getProperty : <K extends "name" | "width" | "height" | "visible">(key: K) => Shape[K]
>"name" : "name"
let widthOrHeight = component.getProperty(cond ? "width" : "height"); // number
>widthOrHeight : number
>component.getProperty(cond ? "width" : "height") : number
>component.getProperty : <K extends "name" | "width" | "height" | "visible">(key: K) => Shape[K]
>component : Component<Shape>
>getProperty : <K extends "name" | "width" | "height" | "visible">(key: K) => Shape[K]
>cond ? "width" : "height" : "width" | "height"
>cond : boolean
>"width" : "width"
>"height" : "height"
let nameOrVisible = component.getProperty(cond ? "name" : "visible"); // string | boolean
>nameOrVisible : string | boolean
>component.getProperty(cond ? "name" : "visible") : string | boolean
>component.getProperty : <K extends "name" | "width" | "height" | "visible">(key: K) => Shape[K]
>component : Component<Shape>
>getProperty : <K extends "name" | "width" | "height" | "visible">(key: K) => Shape[K]
>cond ? "name" : "visible" : "name" | "visible"
>cond : boolean
>"name" : "name"
>"visible" : "visible"
component.setProperty("name", "rectangle");
>component.setProperty("name", "rectangle") : void
>component.setProperty : <K extends "name" | "width" | "height" | "visible">(key: K, value: Shape[K]) => void
>component : Component<Shape>
>setProperty : <K extends "name" | "width" | "height" | "visible">(key: K, value: Shape[K]) => void
>"name" : "name"
>"rectangle" : "rectangle"
component.setProperty(cond ? "width" : "height", 10)
>component.setProperty(cond ? "width" : "height", 10) : void
>component.setProperty : <K extends "name" | "width" | "height" | "visible">(key: K, value: Shape[K]) => void
>component : Component<Shape>
>setProperty : <K extends "name" | "width" | "height" | "visible">(key: K, value: Shape[K]) => void
>cond ? "width" : "height" : "width" | "height"
>cond : boolean
>"width" : "width"
>"height" : "height"
>10 : 10
component.setProperty(cond ? "name" : "visible", true); // Technically not safe
>component.setProperty(cond ? "name" : "visible", true) : void
>component.setProperty : <K extends "name" | "width" | "height" | "visible">(key: K, value: Shape[K]) => void
>component : Component<Shape>
>setProperty : <K extends "name" | "width" | "height" | "visible">(key: K, value: Shape[K]) => void
>cond ? "name" : "visible" : "name" | "visible"
>cond : boolean
>"name" : "name"
>"visible" : "visible"
>true : true
}
function pluck<T, K extends keyof T>(array: T[], key: K) {
>pluck : <T, K extends keyof T>(array: T[], key: K) => T[K][]
>T : T
>K : K
>T : T
>array : T[]
>T : T
>key : K
>K : K
return array.map(x => x[key]);
>array.map(x => x[key]) : T[K][]
>array.map : { <U>(this: [T, T, T, T, T], callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any): [U, U, U, U, U]; <U>(this: [T, T, T, T], callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any): [U, U, U, U]; <U>(this: [T, T, T], callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any): [U, U, U]; <U>(this: [T, T], callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any): [U, U]; <U>(callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any): U[]; }
>array : T[]
>map : { <U>(this: [T, T, T, T, T], callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any): [U, U, U, U, U]; <U>(this: [T, T, T, T], callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any): [U, U, U, U]; <U>(this: [T, T, T], callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any): [U, U, U]; <U>(this: [T, T], callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any): [U, U]; <U>(callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any): U[]; }
>x => x[key] : (x: T) => T[K]
>x : T
>x[key] : T[K]
>x : T
>key : K
}
function f30(shapes: Shape[]) {
>f30 : (shapes: Shape[]) => void
>shapes : Shape[]
>Shape : Shape
let names = pluck(shapes, "name"); // string[]
>names : string[]
>pluck(shapes, "name") : string[]
>pluck : <T, K extends keyof T>(array: T[], key: K) => T[K][]
>shapes : Shape[]
>"name" : "name"
let widths = pluck(shapes, "width"); // number[]
>widths : number[]
>pluck(shapes, "width") : number[]
>pluck : <T, K extends keyof T>(array: T[], key: K) => T[K][]
>shapes : Shape[]
>"width" : "width"
let nameOrVisibles = pluck(shapes, cond ? "name" : "visible"); // (string | boolean)[]
>nameOrVisibles : (string | boolean)[]
>pluck(shapes, cond ? "name" : "visible") : (string | boolean)[]
>pluck : <T, K extends keyof T>(array: T[], key: K) => T[K][]
>shapes : Shape[]
>cond ? "name" : "visible" : "name" | "visible"
>cond : boolean
>"name" : "name"
>"visible" : "visible"
}
function f31<K extends keyof Shape>(key: K) {
>f31 : <K extends "name" | "width" | "height" | "visible">(key: K) => Shape[K]
>K : K
>Shape : Shape
>key : K
>K : K
const shape: Shape = { name: "foo", width: 5, height: 10, visible: true };
>shape : Shape
>Shape : Shape
>{ name: "foo", width: 5, height: 10, visible: true } : { name: string; width: number; height: number; visible: true; }
>name : string
>"foo" : "foo"
>width : number
>5 : 5
>height : number
>10 : 10
>visible : boolean
>true : true
return shape[key]; // Shape[K]
>shape[key] : Shape[K]
>shape : Shape
>key : K
}
function f32<K extends "width" | "height">(key: K) {
>f32 : <K extends "width" | "height">(key: K) => Shape[K]
>K : K
>key : K
>K : K
const shape: Shape = { name: "foo", width: 5, height: 10, visible: true };
>shape : Shape
>Shape : Shape
>{ name: "foo", width: 5, height: 10, visible: true } : { name: string; width: number; height: number; visible: true; }
>name : string
>"foo" : "foo"
>width : number
>5 : 5
>height : number
>10 : 10
>visible : boolean
>true : true
return shape[key]; // Shape[K]
>shape[key] : Shape[K]
>shape : Shape
>key : K
}
class C {
>C : C
public x: string;
>x : string
protected y: string;
>y : string
private z: string;
>z : string
}
// Indexed access expressions have always permitted access to private and protected members.
// For consistency we also permit such access in indexed access types.
function f40(c: C) {
>f40 : (c: C) => void
>c : C
>C : C
type X = C["x"];
>X : string
>C : C
type Y = C["y"];
>Y : string
>C : C
type Z = C["z"];
>Z : string
>C : C
let x: X = c["x"];
>x : string
>X : string
>c["x"] : string
>c : C
>"x" : "x"
let y: Y = c["y"];
>y : string
>Y : string
>c["y"] : string
>c : C
>"y" : "y"
let z: Z = c["z"];
>z : string
>Z : string
>c["z"] : string
>c : C
>"z" : "z"
}

View file

@ -0,0 +1,138 @@
tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(10,18): error TS2304: Cannot find name 'K0'.
tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(20,18): error TS2339: Property 'foo' does not exist on type 'Shape'.
tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(21,18): error TS2339: Property 'foo' does not exist on type 'Shape'.
tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(22,18): error TS2538: Type 'any' cannot be used as an index type.
tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(23,18): error TS2537: Type 'Shape' has no matching index signature for type 'string'.
tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(24,18): error TS2537: Type 'Shape' has no matching index signature for type 'number'.
tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(25,18): error TS2538: Type 'boolean' cannot be used as an index type.
tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(26,18): error TS2538: Type 'void' cannot be used as an index type.
tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(27,18): error TS2538: Type 'undefined' cannot be used as an index type.
tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(28,18): error TS2538: Type '{ x: string; }' cannot be used as an index type.
tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(29,18): error TS2537: Type 'Shape' has no matching index signature for type 'string'.
tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(30,18): error TS2538: Type 'string & number' cannot be used as an index type.
tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(31,18): error TS2537: Type 'Shape' has no matching index signature for type 'string'.
tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(35,21): error TS2537: Type 'string[]' has no matching index signature for type 'string'.
tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(36,21): error TS2538: Type 'boolean' cannot be used as an index type.
tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(41,31): error TS2538: Type 'boolean' cannot be used as an index type.
tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(46,16): error TS2538: Type 'boolean' cannot be used as an index type.
tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(63,33): error TS2345: Argument of type '"size"' is not assignable to parameter of type '"name" | "width" | "height" | "visible"'.
tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(64,33): error TS2345: Argument of type '"name" | "size"' is not assignable to parameter of type '"name" | "width" | "height" | "visible"'.
Type '"size"' is not assignable to type '"name" | "width" | "height" | "visible"'.
tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(66,24): error TS2345: Argument of type '"size"' is not assignable to parameter of type '"name" | "width" | "height" | "visible"'.
tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(67,24): error TS2345: Argument of type '"name" | "size"' is not assignable to parameter of type '"name" | "width" | "height" | "visible"'.
Type '"size"' is not assignable to type '"name" | "width" | "height" | "visible"'.
==== tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts (21 errors) ====
class Shape {
name: string;
width: number;
height: number;
visible: boolean;
}
type Dictionary<T> = { [x: string]: T };
type T00 = keyof K0; // Error
~~
!!! error TS2304: Cannot find name 'K0'.
type T01 = keyof Object;
type T02 = keyof keyof Object;
type T03 = keyof keyof keyof Object;
type T04 = keyof keyof keyof keyof Object;
type T05 = keyof keyof keyof keyof keyof Object;
type T06 = keyof keyof keyof keyof keyof keyof Object;
type T10 = Shape["name"];
type T11 = Shape["foo"]; // Error
~~~~~
!!! error TS2339: Property 'foo' does not exist on type 'Shape'.
type T12 = Shape["name" | "foo"]; // Error
~~~~~~~~~~~~~~
!!! error TS2339: Property 'foo' does not exist on type 'Shape'.
type T13 = Shape[any]; // Error
~~~
!!! error TS2538: Type 'any' cannot be used as an index type.
type T14 = Shape[string]; // Error
~~~~~~
!!! error TS2537: Type 'Shape' has no matching index signature for type 'string'.
type T15 = Shape[number]; // Error
~~~~~~
!!! error TS2537: Type 'Shape' has no matching index signature for type 'number'.
type T16 = Shape[boolean]; // Error
~~~~~~~
!!! error TS2538: Type 'boolean' cannot be used as an index type.
type T17 = Shape[void]; // Error
~~~~
!!! error TS2538: Type 'void' cannot be used as an index type.
type T18 = Shape[undefined]; // Error
~~~~~~~~~
!!! error TS2538: Type 'undefined' cannot be used as an index type.
type T19 = Shape[{ x: string }]; // Error
~~~~~~~~~~~~~
!!! error TS2538: Type '{ x: string; }' cannot be used as an index type.
type T20 = Shape[string | number]; // Error
~~~~~~~~~~~~~~~
!!! error TS2537: Type 'Shape' has no matching index signature for type 'string'.
type T21 = Shape[string & number]; // Error
~~~~~~~~~~~~~~~
!!! error TS2538: Type 'string & number' cannot be used as an index type.
type T22 = Shape[string | boolean]; // Error
~~~~~~~~~~~~~~~~
!!! error TS2537: Type 'Shape' has no matching index signature for type 'string'.
type T30 = string[]["length"];
type T31 = string[][number];
type T32 = string[][string]; // Error
~~~~~~
!!! error TS2537: Type 'string[]' has no matching index signature for type 'string'.
type T33 = string[][boolean]; // Error
~~~~~~~
!!! error TS2538: Type 'boolean' cannot be used as an index type.
type T40 = Dictionary<string>[any];
type T41 = Dictionary<string>[number];
type T42 = Dictionary<string>[string];
type T43 = Dictionary<string>[boolean]; // Error
~~~~~~~
!!! error TS2538: Type 'boolean' cannot be used as an index type.
type T50 = any[any];
type T51 = any[number];
type T52 = any[string];
type T53 = any[boolean]; // Error
~~~~~~~
!!! error TS2538: Type 'boolean' cannot be used as an index type.
type T60 = {}["toString"];
type T61 = []["toString"];
declare let cond: boolean;
function getProperty<T, K extends keyof T>(obj: T, key: K) {
return obj[key];
}
function setProperty<T, K extends keyof T>(obj: T, key: K, value: T[K]) {
obj[key] = value;
}
function f10(shape: Shape) {
let x1 = getProperty(shape, "name");
let x2 = getProperty(shape, "size"); // Error
~~~~~~
!!! error TS2345: Argument of type '"size"' is not assignable to parameter of type '"name" | "width" | "height" | "visible"'.
let x3 = getProperty(shape, cond ? "name" : "size"); // Error
~~~~~~~~~~~~~~~~~~~~~~
!!! error TS2345: Argument of type '"name" | "size"' is not assignable to parameter of type '"name" | "width" | "height" | "visible"'.
!!! error TS2345: Type '"size"' is not assignable to type '"name" | "width" | "height" | "visible"'.
setProperty(shape, "name", "rectangle");
setProperty(shape, "size", 10); // Error
~~~~~~
!!! error TS2345: Argument of type '"size"' is not assignable to parameter of type '"name" | "width" | "height" | "visible"'.
setProperty(shape, cond ? "name" : "size", 10); // Error
~~~~~~~~~~~~~~~~~~~~~~
!!! error TS2345: Argument of type '"name" | "size"' is not assignable to parameter of type '"name" | "width" | "height" | "visible"'.
!!! error TS2345: Type '"size"' is not assignable to type '"name" | "width" | "height" | "visible"'.
}

View file

@ -0,0 +1,90 @@
//// [keyofAndIndexedAccessErrors.ts]
class Shape {
name: string;
width: number;
height: number;
visible: boolean;
}
type Dictionary<T> = { [x: string]: T };
type T00 = keyof K0; // Error
type T01 = keyof Object;
type T02 = keyof keyof Object;
type T03 = keyof keyof keyof Object;
type T04 = keyof keyof keyof keyof Object;
type T05 = keyof keyof keyof keyof keyof Object;
type T06 = keyof keyof keyof keyof keyof keyof Object;
type T10 = Shape["name"];
type T11 = Shape["foo"]; // Error
type T12 = Shape["name" | "foo"]; // Error
type T13 = Shape[any]; // Error
type T14 = Shape[string]; // Error
type T15 = Shape[number]; // Error
type T16 = Shape[boolean]; // Error
type T17 = Shape[void]; // Error
type T18 = Shape[undefined]; // Error
type T19 = Shape[{ x: string }]; // Error
type T20 = Shape[string | number]; // Error
type T21 = Shape[string & number]; // Error
type T22 = Shape[string | boolean]; // Error
type T30 = string[]["length"];
type T31 = string[][number];
type T32 = string[][string]; // Error
type T33 = string[][boolean]; // Error
type T40 = Dictionary<string>[any];
type T41 = Dictionary<string>[number];
type T42 = Dictionary<string>[string];
type T43 = Dictionary<string>[boolean]; // Error
type T50 = any[any];
type T51 = any[number];
type T52 = any[string];
type T53 = any[boolean]; // Error
type T60 = {}["toString"];
type T61 = []["toString"];
declare let cond: boolean;
function getProperty<T, K extends keyof T>(obj: T, key: K) {
return obj[key];
}
function setProperty<T, K extends keyof T>(obj: T, key: K, value: T[K]) {
obj[key] = value;
}
function f10(shape: Shape) {
let x1 = getProperty(shape, "name");
let x2 = getProperty(shape, "size"); // Error
let x3 = getProperty(shape, cond ? "name" : "size"); // Error
setProperty(shape, "name", "rectangle");
setProperty(shape, "size", 10); // Error
setProperty(shape, cond ? "name" : "size", 10); // Error
}
//// [keyofAndIndexedAccessErrors.js]
var Shape = (function () {
function Shape() {
}
return Shape;
}());
function getProperty(obj, key) {
return obj[key];
}
function setProperty(obj, key, value) {
obj[key] = value;
}
function f10(shape) {
var x1 = getProperty(shape, "name");
var x2 = getProperty(shape, "size"); // Error
var x3 = getProperty(shape, cond ? "name" : "size"); // Error
setProperty(shape, "name", "rectangle");
setProperty(shape, "size", 10); // Error
setProperty(shape, cond ? "name" : "size", 10); // Error
}

View file

@ -0,0 +1,167 @@
// @declaration: true
class Shape {
name: string;
width: number;
height: number;
visible: boolean;
}
class Item {
name: string;
price: number;
}
class Options {
visible: "yes" | "no";
}
type Dictionary<T> = { [x: string]: T };
const enum E { A, B, C }
type K00 = keyof any; // string | number
type K01 = keyof string; // number | "toString" | "charAt" | ...
type K02 = keyof number; // "toString" | "toFixed" | "toExponential" | ...
type K03 = keyof boolean; // "valueOf"
type K04 = keyof void; // never
type K05 = keyof undefined; // never
type K06 = keyof null; // never
type K07 = keyof never; // never
type K10 = keyof Shape; // "name" | "width" | "height" | "visible"
type K11 = keyof Shape[]; // number | "length" | "toString" | ...
type K12 = keyof Dictionary<Shape>; // string | number
type K13 = keyof {}; // never
type K14 = keyof Object; // "constructor" | "toString" | ...
type K15 = keyof E; // "toString" | "toFixed" | "toExponential" | ...
type K16 = keyof [string, number]; // number | "0" | "1" | "length" | "toString" | ...
type K17 = keyof (Shape | Item); // "name"
type K18 = keyof (Shape & Item); // "name" | "width" | "height" | "visible" | "price"
type KeyOf<T> = keyof T;
type K20 = KeyOf<Shape>; // "name" | "width" | "height" | "visible"
type K21 = KeyOf<Dictionary<Shape>>; // string | number
type NAME = "name";
type WIDTH_OR_HEIGHT = "width" | "height";
type Q10 = Shape["name"]; // string
type Q11 = Shape["width" | "height"]; // number
type Q12 = Shape["name" | "visible"]; // string | boolean
type Q20 = Shape[NAME]; // string
type Q21 = Shape[WIDTH_OR_HEIGHT]; // number
type Q30 = [string, number][0]; // string
type Q31 = [string, number][1]; // number
type Q32 = [string, number][2]; // string | number
type Q33 = [string, number][E.A]; // string
type Q34 = [string, number][E.B]; // number
type Q35 = [string, number][E.C]; // string | number
type Q36 = [string, number]["0"]; // string
type Q37 = [string, number]["1"]; // string
type Q40 = (Shape | Options)["visible"]; // boolean | "yes" | "no"
type Q41 = (Shape & Options)["visible"]; // true & "yes" | true & "no" | false & "yes" | false & "no"
type Q50 = Dictionary<Shape>["howdy"]; // Shape
type Q51 = Dictionary<Shape>[123]; // Shape
type Q52 = Dictionary<Shape>[E.B]; // Shape
declare let cond: boolean;
function getProperty<T, K extends keyof T>(obj: T, key: K) {
return obj[key];
}
function setProperty<T, K extends keyof T>(obj: T, key: K, value: T[K]) {
obj[key] = value;
}
function f10(shape: Shape) {
let name = getProperty(shape, "name"); // string
let widthOrHeight = getProperty(shape, cond ? "width" : "height"); // number
let nameOrVisible = getProperty(shape, cond ? "name" : "visible"); // string | boolean
setProperty(shape, "name", "rectangle");
setProperty(shape, cond ? "width" : "height", 10);
setProperty(shape, cond ? "name" : "visible", true); // Technically not safe
}
function f11(a: Shape[]) {
let len = getProperty(a, "length"); // number
let shape = getProperty(a, 1000); // Shape
setProperty(a, 1000, getProperty(a, 1001));
}
function f12(t: [Shape, boolean]) {
let len = getProperty(t, "length");
let s1 = getProperty(t, 0); // Shape
let s2 = getProperty(t, "0"); // Shape
let b1 = getProperty(t, 1); // boolean
let b2 = getProperty(t, "1"); // boolean
let x1 = getProperty(t, 2); // Shape | boolean
}
function f13(foo: any, bar: any) {
let x = getProperty(foo, "x"); // any
let y = getProperty(foo, 100); // any
let z = getProperty(foo, bar); // any
}
class Component<PropType> {
props: PropType;
getProperty<K extends keyof PropType>(key: K) {
return this.props[key];
}
setProperty<K extends keyof PropType>(key: K, value: PropType[K]) {
this.props[key] = value;
}
}
function f20(component: Component<Shape>) {
let name = component.getProperty("name"); // string
let widthOrHeight = component.getProperty(cond ? "width" : "height"); // number
let nameOrVisible = component.getProperty(cond ? "name" : "visible"); // string | boolean
component.setProperty("name", "rectangle");
component.setProperty(cond ? "width" : "height", 10)
component.setProperty(cond ? "name" : "visible", true); // Technically not safe
}
function pluck<T, K extends keyof T>(array: T[], key: K) {
return array.map(x => x[key]);
}
function f30(shapes: Shape[]) {
let names = pluck(shapes, "name"); // string[]
let widths = pluck(shapes, "width"); // number[]
let nameOrVisibles = pluck(shapes, cond ? "name" : "visible"); // (string | boolean)[]
}
function f31<K extends keyof Shape>(key: K) {
const shape: Shape = { name: "foo", width: 5, height: 10, visible: true };
return shape[key]; // Shape[K]
}
function f32<K extends "width" | "height">(key: K) {
const shape: Shape = { name: "foo", width: 5, height: 10, visible: true };
return shape[key]; // Shape[K]
}
class C {
public x: string;
protected y: string;
private z: string;
}
// Indexed access expressions have always permitted access to private and protected members.
// For consistency we also permit such access in indexed access types.
function f40(c: C) {
type X = C["x"];
type Y = C["y"];
type Z = C["z"];
let x: X = c["x"];
let y: Y = c["y"];
let z: Z = c["z"];
}

View file

@ -0,0 +1,68 @@
class Shape {
name: string;
width: number;
height: number;
visible: boolean;
}
type Dictionary<T> = { [x: string]: T };
type T00 = keyof K0; // Error
type T01 = keyof Object;
type T02 = keyof keyof Object;
type T03 = keyof keyof keyof Object;
type T04 = keyof keyof keyof keyof Object;
type T05 = keyof keyof keyof keyof keyof Object;
type T06 = keyof keyof keyof keyof keyof keyof Object;
type T10 = Shape["name"];
type T11 = Shape["foo"]; // Error
type T12 = Shape["name" | "foo"]; // Error
type T13 = Shape[any]; // Error
type T14 = Shape[string]; // Error
type T15 = Shape[number]; // Error
type T16 = Shape[boolean]; // Error
type T17 = Shape[void]; // Error
type T18 = Shape[undefined]; // Error
type T19 = Shape[{ x: string }]; // Error
type T20 = Shape[string | number]; // Error
type T21 = Shape[string & number]; // Error
type T22 = Shape[string | boolean]; // Error
type T30 = string[]["length"];
type T31 = string[][number];
type T32 = string[][string]; // Error
type T33 = string[][boolean]; // Error
type T40 = Dictionary<string>[any];
type T41 = Dictionary<string>[number];
type T42 = Dictionary<string>[string];
type T43 = Dictionary<string>[boolean]; // Error
type T50 = any[any];
type T51 = any[number];
type T52 = any[string];
type T53 = any[boolean]; // Error
type T60 = {}["toString"];
type T61 = []["toString"];
declare let cond: boolean;
function getProperty<T, K extends keyof T>(obj: T, key: K) {
return obj[key];
}
function setProperty<T, K extends keyof T>(obj: T, key: K, value: T[K]) {
obj[key] = value;
}
function f10(shape: Shape) {
let x1 = getProperty(shape, "name");
let x2 = getProperty(shape, "size"); // Error
let x3 = getProperty(shape, cond ? "name" : "size"); // Error
setProperty(shape, "name", "rectangle");
setProperty(shape, "size", 10); // Error
setProperty(shape, cond ? "name" : "size", 10); // Error
}