2017-07-30 19 views
7

Tôi có map chức năng:Implicit loại suy luận với các đối số hàm trong nguyên cảo

const map = <T, U>(f: (x: T) => U, arr: T[]): U[] => { 
    return arr.map((val) => f(val)); 
} 

Khi tôi gọi map với chức năng ẩn danh như một gọi lại, đó là kiểu trả về là đúng:

// `x1` variable type here is { name: string }[], which is correct 
const x1 = map(x => x, [{name: 'John'}]); 

Nhưng khi tôi cung cấp chức năng identity thay vì ẩn danh, loại trả về sai:

const identity = <T>(x: T) => x 
// return type of `x2` is {}[] here 
const x2 = map(identity, [{name: 'John'}]); 

Cách nhận kết quả loại chính xác cho ví dụ thứ 2, mà không cung cấp đối số loại rõ ràng cho hàm map?

+1

Điều gì sẽ xảy ra nếu bạn chỉ định loại trả về là 'T' trên' danh tính'? – jonrsharpe

+0

@jonrsharpe cùng một kết quả .. – 1ven

+2

Nó hoạt động tốt nếu bạn chuyển đổi thứ tự của các đối số 'map()'. Tôi đoán nó buộc trình biên dịch phải phù hợp với loại phần tử mảng đầu tiên? Tôi không biết nếu có một cách để có được suy luận để làm việc theo thứ tự bạn có. – jcalz

Trả lời

2

Sau một số lần thử, tôi thành thật nghi ngờ TypeScript có thể theo dõi bạn đến mức đó. Ví dụ:

const x4 = map(identity, [2]); 
// x4 is '{}[]' 

mà thậm chí còn sai hơn cả ví dụ của bạn.

Một số xét nghiệm khác:

const x2 = map(<({ name: string }) => { name: string }>identity, [{ name: 'John' }]); 
// x2 is '{ name: string }[]' 

Và:

const double = (x: number) => 2 * x; 
const x3 = map(double, [2]); 
// x3 is 'number[]' 

này cho phép tôi kết luận nguyên cảo mà chỉ là không thể phá vỡ tất cả những gì Generics xuống đến một loại có ý nghĩa và chỉ nói {} .

Các vấn đề liên quan