TypeScript keyof 和 typeof
Posted Himmelbleu
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了TypeScript keyof 和 typeof相关的知识,希望对你有一定的参考价值。
typeof
typeof
是 JS 本身就有的一个操作符,只不过在 TS 中多了一个功能。typeof
在 JS 中是获取变量的类型字符串:
console.log(typeof 42);
// "number"
console.log(typeof \'blubber\');
// "string"
console.log(typeof true);
// "boolean"
在 TS 中的 typeof
可以返回一个变量的 TS 类型,也可以返回一个变量的类型字符串:
let num = 42;
type A1 = typeof num;
// ^? number
console.log(typeof 42);
// "number"
区别之处就是你要用在 interface 或者 type 关键字声明的类型变量中,而不是当做一个普通变量进行输出。
注意:TS 的类型不可以直接通过 log 打印到控制台,只有变量才可以,而非类型变量。
keyof
keyof
不是 JS 特有的,而是 TS 特有的,keyof 用于得到一个对象的属性的联合类型。
interface Person
name: string;
age: number;
type A1 = keyof Person;
// ^? "name" | "age"
keyof
操作的是一个 TS 类型;typeof
操作的是一个变量,返回变量对应的类型字符串或变量对应的 TS 类型。
keyof 和 typeof
typeof
操作一个变量,运算出 TS 类型,keyof
运算一个已知的 TS 类型。两者结合起来:keyof
通过由 typeof
运算的对象的 TS 类型,从而得到该对象的属性联合类型。
const obj =
name: "小明",
age: 12
type A1 = keyof typeof obj;
// ^? "name" | "age"
如果 obj 每一次的属性都是不一样的,两者结合起来可以实现动态得到一个对象的 TS 类型,非常的有用!
Typescript 'keyof' 关键字在使用 react setState 函数时出错
【中文标题】Typescript \'keyof\' 关键字在使用 react setState 函数时出错【英文标题】:Typescript 'keyof' keyword makes error when using with react setState functionTypescript 'keyof' 关键字在使用 react setState 函数时出错 【发布时间】:2018-11-15 20:10:16 【问题描述】:我正在用 react 和 typescript 编写 Simple LoginForm。
interface State
username: string;
password: string;
class LoginForm extends React.Component<Props, State>
readonly state: Readonly<State> =
username: '',
password: ''
onChange = (key: keyof State) => (e: React.FormEvent<HTMLInputElement>) =>
const value = e.currentTarget.value;
this.setState( [key]: value ); // error
render()
return (
...
<TextField
...
onChange=this.onChange('username')
/>
<TextField
...
onChange=this.onChange('password')
/>
...
)
Typescript 在 setState 行中编译失败,出现错误。
类型参数 ' [x: string]: string; ' 不可分配给“State |”类型的参数((prevState: Readonly, props: Props) => State | Pick'. 类型 ' [x: string]: string; 中缺少属性 'username' '。
this.onChange 函数中的“key”参数只允许“用户名”或“密码”,如我所料。这意味着打字稿知道 typeof 'key' 参数必须是 'username' 或 'password'。这很明显,因为我将其定义为 (key: key of State)。
但是为什么在 setState 函数中,typeof 'key' 参数变成了普通字符串呢?
谢谢。
【问题讨论】:
【参考方案1】:添加它作为替代方案,因为这解决了我的问题。
似乎在设置状态 this.setState(prop: value)
时,React TS 有时可以期待完整的 state
@jcalz 对所选答案的推测。
this.setState(
...this.state,
[key]: value
);
有关此问题的最佳做法的更多信息,请点击此处: https://github.com/DefinitelyTyped/DefinitelyTyped/issues/26635
【讨论】:
【参考方案2】:试试这个代码:
onChange = (key: keyof IState) => (event: React.FormEvent<HTMLInputElement>) =>
this.setState(
[key]: event.currentTarget.value
as Pick<IState, keyof IState>);
【讨论】:
【参考方案3】:您遇到了known TypeScript bug,其中联合类型的计算属性被扩展为索引签名。 看起来对于 TypeScript 3.0,这将是 fixed,但这并不确定。
您现在应该使用的解决方法是 assert 该对象是预期的类型:
this.setState( [key]: value as Record<typeof key, typeof value>);
我对 React 不够熟悉,无法知道 setState()
是否期待完整的 State
,但请注意 [key]: value
是 Partial<State>
,因为它不会同时包含键...和 TypeScript不会抓住这个,因为key
是一个联合类型。所以在运行时要小心。您可能希望将断言作为
this.setState( [key]: value as Partial<State>);
如果这导致了错误,那么你应该修复它。
希望对您有所帮助。祝你好运!
【讨论】:
谢谢。你节省了我的时间。以上是关于TypeScript keyof 和 typeof的主要内容,如果未能解决你的问题,请参考以下文章
[TypeScript] type、typeof、keyof
打字稿:对象和原语之间的keyof typeof联合总是永远不会