2017-02-07 13 views
6

Mới nhất @types/react (v15.0.6) sử dụng các tính năng được thêm vào trong TypeScript 2.1 cho setState, cụ thể là Pick<S, K>. Đó là một điều tốt, bởi vì bây giờ các kiểu gõ là chính xác, bởi vì trước khi các kiểu gõ cập nhật "không biết" rằng setState đang hợp nhất this.state, thay vì thay thế nó.Chọn <S, K> loại bằng phím năng động/được tính

Ngoài ra, sử dụng Pick làm cho chức năng setState rất nghiêm ngặt về mặt được phép. Đó là không còn có thể thêm các thuộc tính cho state mà không được định nghĩa trong định nghĩa thành phần (thứ hai chung của React.Component

Nhưng nó cũng là khó khăn hơn để xác định một handler cập nhật động Ví dụ:..

import * as React from 'react'; 


interface Person { 
    name: string; 
    age: number|undefined; 
} 


export default class PersonComponent extends React.Component<void, Person> { 
    constructor(props:any) { 
    super(props); 

    this.state = { 
     name: '', 
     age: undefined 
    }; 
    this.handleUpdate = this.handleUpdate.bind(this); 
    } 

    handleUpdate (e:React.SyntheticEvent<HTMLInputElement>) { 
    const key = e.currentTarget.name as keyof Person; 
    const value = e.currentTarget.value; 
    this.setState({ [key]: value }); 
    } 

    render() { 
    return (
     <form> 
     <input type="text" name="name" value={this.state.name} onChange={this.handleUpdate} /> 
     <input type="text" name="age" value={this.state.age} onChange={this.handleUpdate} /> 
     </form> 
    ); 
    } 
} 

chức năng setState sẽ ném các lỗi sau

[ts] Argument of type '{ [x: string]: string; }' is not assignable 
    to parameter of type 'Pick<Person, "name" | "age">'. 
     Property 'name' is missing in type '{ [x: string]: string; }'. 

mặc dù loại key"name" | "age".

Tôi không thể tìm thấy giải pháp cho điều này, ngoài việc có chức năng updateNameupdateAge riêng biệt. Có ai biết cách sử dụng Pick với các giá trị khóa động không?

Trả lời

5

Vì vậy, sau khi nghiên cứu thêm, tôi có thể cung cấp thêm một chút ngữ cảnh về những gì đang xảy ra trong mã trên.

Khi bạn làm điều gì đó như const name = 'Bob' loại biến name'Bob'không phải chuỗi. Tuy nhiên, nếu bạn thay thế const bằng let (let name = 'Bob') biến số name sẽ thuộc loại string.

Khái niệm này được gọi là "mở rộng". Về cơ bản, nó có nghĩa là hệ thống kiểu cố gắng càng rõ ràng càng tốt. Vì không thể gán lại const TypeScript có thể suy ra loại chính xác. Các câu lệnh let có thể được chỉ định lại. Do đó, TypeScript sẽ phỏng đoán string (trong ví dụ trên) làm loại name.

Điều tương tự cũng xảy ra với const key = e.currentTarget.name as keyof Person. key sẽ là của (công đoàn) loại "name"|"age", đó là chính xác những gì chúng tôi muốn nó được. Nhưng trong biểu thức this.setState({ [key]: value }); biến key được (không chính xác) được mở rộng thành string.


tl; dr; Dường như có lỗi trong TypeScript. Tôi đã đăng sự cố lên repo Github và nhóm TypeScript is investigating the problem. :)

Giải pháp tạm thời bạn có thể làm:

this.setState({ [key as any]: value }); 
Các vấn đề liên quan