Add test to verify use of Pick<T, K> with setState
This commit is contained in:
parent
00f7d85a62
commit
7fdfcf11cd
3 changed files with 192 additions and 4 deletions
|
@ -26,9 +26,19 @@ tests/cases/conformance/types/mapped/mappedTypeErrors.ts(78,59): error TS2345: A
|
||||||
Object literal may only specify known properties, and 'z' does not exist in type 'Readonly<{ x: number; y: number; }>'.
|
Object literal may only specify known properties, and 'z' does not exist in type 'Readonly<{ x: number; y: number; }>'.
|
||||||
tests/cases/conformance/types/mapped/mappedTypeErrors.ts(84,58): error TS2345: Argument of type '{ x: number; y: number; z: number; }' is not assignable to parameter of type 'Partial<{ x: number; y: number; }>'.
|
tests/cases/conformance/types/mapped/mappedTypeErrors.ts(84,58): error TS2345: Argument of type '{ x: number; y: number; z: number; }' is not assignable to parameter of type 'Partial<{ x: number; y: number; }>'.
|
||||||
Object literal may only specify known properties, and 'z' does not exist in type 'Partial<{ x: number; y: number; }>'.
|
Object literal may only specify known properties, and 'z' does not exist in type 'Partial<{ x: number; y: number; }>'.
|
||||||
|
tests/cases/conformance/types/mapped/mappedTypeErrors.ts(106,15): error TS2345: Argument of type '{ a: undefined; }' is not assignable to parameter of type 'Pick<Foo, "a">'.
|
||||||
|
Types of property 'a' are incompatible.
|
||||||
|
Type 'undefined' is not assignable to type 'string'.
|
||||||
|
tests/cases/conformance/types/mapped/mappedTypeErrors.ts(107,17): error TS2345: Argument of type '{ c: boolean; }' is not assignable to parameter of type 'Pick<Foo, "a" | "b">'.
|
||||||
|
Object literal may only specify known properties, and 'c' does not exist in type 'Pick<Foo, "a" | "b">'.
|
||||||
|
tests/cases/conformance/types/mapped/mappedTypeErrors.ts(124,12): error TS2345: Argument of type '{ a: undefined; }' is not assignable to parameter of type 'Pick<Foo, "a">'.
|
||||||
|
Types of property 'a' are incompatible.
|
||||||
|
Type 'undefined' is not assignable to type 'string'.
|
||||||
|
tests/cases/conformance/types/mapped/mappedTypeErrors.ts(125,14): error TS2345: Argument of type '{ c: boolean; }' is not assignable to parameter of type 'Pick<Foo, "a" | "b">'.
|
||||||
|
Object literal may only specify known properties, and 'c' does not exist in type 'Pick<Foo, "a" | "b">'.
|
||||||
|
|
||||||
|
|
||||||
==== tests/cases/conformance/types/mapped/mappedTypeErrors.ts (17 errors) ====
|
==== tests/cases/conformance/types/mapped/mappedTypeErrors.ts (21 errors) ====
|
||||||
|
|
||||||
interface Shape {
|
interface Shape {
|
||||||
name: string;
|
name: string;
|
||||||
|
@ -158,4 +168,59 @@ tests/cases/conformance/types/mapped/mappedTypeErrors.ts(84,58): error TS2345: A
|
||||||
~~~~
|
~~~~
|
||||||
!!! error TS2345: Argument of type '{ x: number; y: number; z: number; }' is not assignable to parameter of type 'Partial<{ x: number; y: number; }>'.
|
!!! error TS2345: Argument of type '{ x: number; y: number; z: number; }' is not assignable to parameter of type 'Partial<{ x: number; y: number; }>'.
|
||||||
!!! error TS2345: Object literal may only specify known properties, and 'z' does not exist in type 'Partial<{ x: number; y: number; }>'.
|
!!! error TS2345: Object literal may only specify known properties, and 'z' does not exist in type 'Partial<{ x: number; y: number; }>'.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Verify use of Pick<T, K> for setState functions (#12793)
|
||||||
|
|
||||||
|
interface Foo {
|
||||||
|
a: string;
|
||||||
|
b?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
function setState<T, K extends keyof T>(obj: T, props: Pick<T, K>) {
|
||||||
|
for (let k in props) {
|
||||||
|
obj[k] = props[k];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let foo: Foo = { a: "hello", b: 42 };
|
||||||
|
setState(foo, { a: "test", b: 43 })
|
||||||
|
setState(foo, { a: "hi" });
|
||||||
|
setState(foo, { b: undefined });
|
||||||
|
setState(foo, { });
|
||||||
|
setState(foo, foo);
|
||||||
|
setState(foo, { a: undefined }); // Error
|
||||||
|
~~~~~~~~~~~~~~~~
|
||||||
|
!!! error TS2345: Argument of type '{ a: undefined; }' is not assignable to parameter of type 'Pick<Foo, "a">'.
|
||||||
|
!!! error TS2345: Types of property 'a' are incompatible.
|
||||||
|
!!! error TS2345: Type 'undefined' is not assignable to type 'string'.
|
||||||
|
setState(foo, { c: true }); // Error
|
||||||
|
~~~~~~~
|
||||||
|
!!! error TS2345: Argument of type '{ c: boolean; }' is not assignable to parameter of type 'Pick<Foo, "a" | "b">'.
|
||||||
|
!!! error TS2345: Object literal may only specify known properties, and 'c' does not exist in type 'Pick<Foo, "a" | "b">'.
|
||||||
|
|
||||||
|
class C<T> {
|
||||||
|
state: T;
|
||||||
|
setState<K extends keyof T>(props: Pick<T, K>) {
|
||||||
|
for (let k in props) {
|
||||||
|
this.state[k] = props[k];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let c = new C<Foo>();
|
||||||
|
c.setState({ a: "test", b: 43 });
|
||||||
|
c.setState({ a: "hi" });
|
||||||
|
c.setState({ b: undefined });
|
||||||
|
c.setState({ });
|
||||||
|
c.setState(foo);
|
||||||
|
c.setState({ a: undefined }); // Error
|
||||||
|
~~~~~~~~~~~~~~~~
|
||||||
|
!!! error TS2345: Argument of type '{ a: undefined; }' is not assignable to parameter of type 'Pick<Foo, "a">'.
|
||||||
|
!!! error TS2345: Types of property 'a' are incompatible.
|
||||||
|
!!! error TS2345: Type 'undefined' is not assignable to type 'string'.
|
||||||
|
c.setState({ c: true }); // Error
|
||||||
|
~~~~~~~
|
||||||
|
!!! error TS2345: Argument of type '{ c: boolean; }' is not assignable to parameter of type 'Pick<Foo, "a" | "b">'.
|
||||||
|
!!! error TS2345: Object literal may only specify known properties, and 'c' does not exist in type 'Pick<Foo, "a" | "b">'.
|
||||||
|
|
|
@ -83,7 +83,48 @@ function f21() {
|
||||||
let x1 = objAndPartial({ x: 0, y: 0 }, { x: 1 });
|
let x1 = objAndPartial({ x: 0, y: 0 }, { x: 1 });
|
||||||
let x2 = objAndPartial({ x: 0, y: 0 }, { x: 1, y: 1 });
|
let x2 = objAndPartial({ x: 0, y: 0 }, { x: 1, y: 1 });
|
||||||
let x3 = objAndPartial({ x: 0, y: 0 }, { x: 1, y: 1, z: 1 }); // Error
|
let x3 = objAndPartial({ x: 0, y: 0 }, { x: 1, y: 1, z: 1 }); // Error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Verify use of Pick<T, K> for setState functions (#12793)
|
||||||
|
|
||||||
|
interface Foo {
|
||||||
|
a: string;
|
||||||
|
b?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
function setState<T, K extends keyof T>(obj: T, props: Pick<T, K>) {
|
||||||
|
for (let k in props) {
|
||||||
|
obj[k] = props[k];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let foo: Foo = { a: "hello", b: 42 };
|
||||||
|
setState(foo, { a: "test", b: 43 })
|
||||||
|
setState(foo, { a: "hi" });
|
||||||
|
setState(foo, { b: undefined });
|
||||||
|
setState(foo, { });
|
||||||
|
setState(foo, foo);
|
||||||
|
setState(foo, { a: undefined }); // Error
|
||||||
|
setState(foo, { c: true }); // Error
|
||||||
|
|
||||||
|
class C<T> {
|
||||||
|
state: T;
|
||||||
|
setState<K extends keyof T>(props: Pick<T, K>) {
|
||||||
|
for (let k in props) {
|
||||||
|
this.state[k] = props[k];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let c = new C<Foo>();
|
||||||
|
c.setState({ a: "test", b: 43 });
|
||||||
|
c.setState({ a: "hi" });
|
||||||
|
c.setState({ b: undefined });
|
||||||
|
c.setState({ });
|
||||||
|
c.setState(foo);
|
||||||
|
c.setState({ a: undefined }); // Error
|
||||||
|
c.setState({ c: true }); // Error
|
||||||
|
|
||||||
|
|
||||||
//// [mappedTypeErrors.js]
|
//// [mappedTypeErrors.js]
|
||||||
function f1(x) {
|
function f1(x) {
|
||||||
|
@ -124,6 +165,37 @@ function f21() {
|
||||||
var x2 = objAndPartial({ x: 0, y: 0 }, { x: 1, y: 1 });
|
var x2 = objAndPartial({ x: 0, y: 0 }, { x: 1, y: 1 });
|
||||||
var x3 = objAndPartial({ x: 0, y: 0 }, { x: 1, y: 1, z: 1 }); // Error
|
var x3 = objAndPartial({ x: 0, y: 0 }, { x: 1, y: 1, z: 1 }); // Error
|
||||||
}
|
}
|
||||||
|
function setState(obj, props) {
|
||||||
|
for (var k in props) {
|
||||||
|
obj[k] = props[k];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var foo = { a: "hello", b: 42 };
|
||||||
|
setState(foo, { a: "test", b: 43 });
|
||||||
|
setState(foo, { a: "hi" });
|
||||||
|
setState(foo, { b: undefined });
|
||||||
|
setState(foo, {});
|
||||||
|
setState(foo, foo);
|
||||||
|
setState(foo, { a: undefined }); // Error
|
||||||
|
setState(foo, { c: true }); // Error
|
||||||
|
var C = (function () {
|
||||||
|
function C() {
|
||||||
|
}
|
||||||
|
C.prototype.setState = function (props) {
|
||||||
|
for (var k in props) {
|
||||||
|
this.state[k] = props[k];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return C;
|
||||||
|
}());
|
||||||
|
var c = new C();
|
||||||
|
c.setState({ a: "test", b: 43 });
|
||||||
|
c.setState({ a: "hi" });
|
||||||
|
c.setState({ b: undefined });
|
||||||
|
c.setState({});
|
||||||
|
c.setState(foo);
|
||||||
|
c.setState({ a: undefined }); // Error
|
||||||
|
c.setState({ c: true }); // Error
|
||||||
|
|
||||||
|
|
||||||
//// [mappedTypeErrors.d.ts]
|
//// [mappedTypeErrors.d.ts]
|
||||||
|
@ -168,3 +240,14 @@ declare function objAndReadonly<T>(primary: T, secondary: Readonly<T>): T;
|
||||||
declare function objAndPartial<T>(primary: T, secondary: Partial<T>): T;
|
declare function objAndPartial<T>(primary: T, secondary: Partial<T>): T;
|
||||||
declare function f20(): void;
|
declare function f20(): void;
|
||||||
declare function f21(): void;
|
declare function f21(): void;
|
||||||
|
interface Foo {
|
||||||
|
a: string;
|
||||||
|
b?: number;
|
||||||
|
}
|
||||||
|
declare function setState<T, K extends keyof T>(obj: T, props: Pick<T, K>): void;
|
||||||
|
declare let foo: Foo;
|
||||||
|
declare class C<T> {
|
||||||
|
state: T;
|
||||||
|
setState<K extends keyof T>(props: Pick<T, K>): void;
|
||||||
|
}
|
||||||
|
declare let c: C<Foo>;
|
||||||
|
|
|
@ -84,4 +84,44 @@ function f21() {
|
||||||
let x1 = objAndPartial({ x: 0, y: 0 }, { x: 1 });
|
let x1 = objAndPartial({ x: 0, y: 0 }, { x: 1 });
|
||||||
let x2 = objAndPartial({ x: 0, y: 0 }, { x: 1, y: 1 });
|
let x2 = objAndPartial({ x: 0, y: 0 }, { x: 1, y: 1 });
|
||||||
let x3 = objAndPartial({ x: 0, y: 0 }, { x: 1, y: 1, z: 1 }); // Error
|
let x3 = objAndPartial({ x: 0, y: 0 }, { x: 1, y: 1, z: 1 }); // Error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Verify use of Pick<T, K> for setState functions (#12793)
|
||||||
|
|
||||||
|
interface Foo {
|
||||||
|
a: string;
|
||||||
|
b?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
function setState<T, K extends keyof T>(obj: T, props: Pick<T, K>) {
|
||||||
|
for (let k in props) {
|
||||||
|
obj[k] = props[k];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let foo: Foo = { a: "hello", b: 42 };
|
||||||
|
setState(foo, { a: "test", b: 43 })
|
||||||
|
setState(foo, { a: "hi" });
|
||||||
|
setState(foo, { b: undefined });
|
||||||
|
setState(foo, { });
|
||||||
|
setState(foo, foo);
|
||||||
|
setState(foo, { a: undefined }); // Error
|
||||||
|
setState(foo, { c: true }); // Error
|
||||||
|
|
||||||
|
class C<T> {
|
||||||
|
state: T;
|
||||||
|
setState<K extends keyof T>(props: Pick<T, K>) {
|
||||||
|
for (let k in props) {
|
||||||
|
this.state[k] = props[k];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let c = new C<Foo>();
|
||||||
|
c.setState({ a: "test", b: 43 });
|
||||||
|
c.setState({ a: "hi" });
|
||||||
|
c.setState({ b: undefined });
|
||||||
|
c.setState({ });
|
||||||
|
c.setState(foo);
|
||||||
|
c.setState({ a: undefined }); // Error
|
||||||
|
c.setState({ c: true }); // Error
|
||||||
|
|
Loading…
Reference in a new issue