我以为我明白了新的目的TS 2.1 Pick type https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-1.html#partial-readonly-record-and-pick,但后来我看到它是如何在 React 类型定义中使用的 https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/react/index.d.ts#L171我不明白:
declare class Component<S> {
setState<K extends keyof S>(state: Pick<S, K>, callback?: () => any): void;
state: Readonly<S>;
}
这允许你这样做:
interface PersonProps {
name: string;
age: number;
}
class Person extends Component<{}, PersonProps> {
test() {
this.setState({ age: 123 });
}
}
我的困惑是keyof S
is { name, age }
但我打电话setState()
仅与age
——为什么它不抱怨失踪name
?
我的第一个想法是因为Pick
是一种索引类型,它根本不需要所有键都存在。说得通。但如果我尝试直接分配类型:
const ageState: Pick<PersonProps, keyof PersonProps> = { age: 123 };
It does抱怨失踪name
key:
Type '{ age: number; }' is not assignable to type 'Pick<PersonProps, "name" | "age">'.
Property 'name' is missing in type '{ age: number; }'.
我不明白这一点。它seems我所做的只是填写S
与类型S
已经分配给,并且它从允许sub-set要求的关键all键。这是一个很大的区别。这是在操场上 http://www.typescriptlang.org/play/#src=declare%20class%20Component%3CP%2C%20S%3E%20%7B%0A%20%20%20%20setState%3CK%20extends%20keyof%20S%3E(state%3A%20Pick%3CS%2C%20K%3E%2C%20callback%3F%3A%20()%20%3D%3E%20any)%3A%20void%3B%0A%20%20%20%20state%3A%20Readonly%3CS%3E%3B%0A%7D%0A%0Ainterface%20PersonProps%20%7B%0A%20%20name%3A%20string%3B%0A%20%20age%3A%20number%3B%0A%7D%0A%0Aclass%20Person%20extends%20Component%3C%7B%7D%2C%20PersonProps%3E%20%7B%0A%20%20test()%20%7B%0A%20%20%20%20const%20person%3A%20Pick%3CPersonProps%2C%20keyof%20PersonProps%3E%20%3D%20%7B%20age%3A%20123%20%7D%3B%0A%20%20%20%20this.setState(%7B%20age%3A%20123%20%7D)%3B%0A%20%20%7D%0A%7D。谁能解释这种行为?