Ich dachte, ich den Zweck des neuen TS 2.1 Pick
type verstanden, aber dann sah ich how it was being used in the React type definitions und ich verstehe nicht:Warum erlaubt das neue `Pick <T, K extends keyof T>` -Typ Subsets von `K` in Reacts` setState() `?
declare class Component<S> {
setState<K extends keyof S>(state: Pick<S, K>, callback?:() => any): void;
state: Readonly<S>;
}
Welche Sie dies tun können:
interface PersonProps {
name: string;
age: number;
}
class Person extends Component<{}, PersonProps> {
test() {
this.setState({ age: 123 });
}
}
Meine Verwirrung ist hier dass keyof S
ist { name, age }
, aber ich rufe setState()
mit nur age
- warum beschwert es sich nicht über die fehlende name
?
Mein erster Gedanke ist, dass, weil Pick
ein Indextyp ist, es einfach nicht alle Schlüssel benötigt, um zu existieren. Macht Sinn. Aber wenn ich versuche, direkt den Typ zuzuordnen:
const ageState: Pick<PersonProps, keyof PersonProps> = { age: 123 };
Es hat beschweren sich über die fehlende name
Schlüssel:
Type '{ age: number; }' is not assignable to type 'Pick<PersonProps, "name" | "age">'.
Property 'name' is missing in type '{ age: number; }'.
ich das nicht verstehen. Es scheint alles, was ich war in S
mit dem Typ füllen haben, dass S
bereits zugeordnet ist, und es ging von so dass ein Untersatz der Schlüssel zu erfordern alle Tasten. Das ist ein großer Unterschied. Here it is in the Playground. Kann jemand dieses Verhalten erklären?
* Die Art '„Alter“' kann gesagt werden, den Typ '„name“erweitern | "age" '. * Ah, das hätte ich nicht gedacht, ich würde das" name "| denken "Alter" "verlängert" "Alter", nicht umgekehrt. Danke für die Erklärung! – Aaron
Entschuldigen Sie, dass ich das noch einmal anprangere, aber während ich das Verhalten jetzt verstehe (danke!), Kann ich nicht wirklich rationalisieren, wie "Alter" ein Super-Typ von "Alter" ist "name" 'und kein Untertyp, obwohl es klar ist, wie der Compiler es sieht. Es scheint, dass die umgekehrte Beziehung zwischen den scheinbar äquivalenten Schnittstellen '{name, age}' und 'age} besteht. Kannst du diese Logik erklären? – Aaron
In einem generischen Typ Einschränkung, ist es vielleicht am besten zu lesen "erweitert" als "ist ein spezifischer Typ von." Betrachte 'type AB =" a "| "b"; "und" type ABC = "a" | "b" | "c"; ". Wenn Sie eine Variable 'const abc: ABC = "c"; 'haben, können Sie dies nicht einer Variablen vom Typ' AB 'zuweisen, aber jeder gültige Wert vom Typ' AB 'ist ein gültiger Wert von' ABC '. Da "AB" eine spezifischere Art von "ABC" ist, kann "AB" als * extend * "ABC" bezeichnet werden. –