microsoft / microsoft/TypeScript

type inference breaks with composition function using extend on generic arguments

Đang mở
#44,384 0 bình luận 0 reaction 0 người được giao Xem trên GitHub

Chưa có ai nhận issue này.

Needs Investigation
Ngôn ngữ chính
Go
Star
111k
Fork
14.4k
Merge trung bình
1 ngày 19 giờ
Pull request đã merge (30 ngày)
117

Mô tả

Bug Report

Type inference breaks with composition function using extend on generic arguments. I came across this issue while trying to implement composition for type guard functions see. it worked mostly but in some cases was getting strange type error demonstrated here, then I tried to change type guards with functions and the issue has persisted. Meaning that it's more general issue and not specific to type guards.

🔎 Search Terms

type guard composition extend inference

🕗 Version & Regression Information

Tested on ts@4.0-4.4 and all the versions have this issue

⏯ Playground Link

Playground link with relevant code

💻 Code
type Func<Input, Output> = (value: Input) => Output;

const flow =<I, O extends I, O2 extends O>
  (f: Func<I, O>,g: Func<O, O2>): Func<I, O2> =>
    (i: I): O2 => g(f(i))

const pipe = <I, O>
  (i: I, f: Func<I,O>): O =>
    f(i)


type ABC = AB | "C"
type AB = "A" | "B"
declare const ab: AB | undefined
declare const isB: Func<ABC,"B">
declare function notUndefined<T>(input: T | undefined): T


const b: "B" = pipe(
    ab,
    // infered type is:
    // flow<
    //   AB | undefined
    // , AB | undefined <---- here is error `udefined` shuold be removed
    // , "B">
    // ( f: Func<AB | undefined, AB | undefined>
    // , g: Func<AB | undefined, "B">
    // ): Func<...>
    flow(notUndefined, isB)
    //                 ~~~
    // because of incorectly infered type getting this error:
    //  Argument of type 'Func<ABC, "B">' is not assignable to parameter of type 'Func<AB | undefined, "B">'.
    //   Type 'AB | undefined' is not assignable to type 'ABC'.
    //     Type 'undefined' is not assignable to type 'ABC'.(2345)
    
    // if I specify type arguments it will work fine:
    // flow<AB | undefined,AB,"B">(notUndefined, isB)   
)
 


// NOTE: if we were to use notUndefined without generic argument all would be just fine:
// declare function notUndefined(input: AB | undefined): AB

// NOTE: both of this work just fine
const abnn1: AB = pipe(ab, notUndefined)
const abnn2: AB = pipe(ab, flow(notUndefined,notUndefined))

// NOTE following lines compiling proves that `isB: Func<ABC,"B">` is asignable to `isB2: Func<AB, "B">` 
declare const isB2: Func<AB, "B">
declare const acceptIsB2: (check: Func<AB, "B">) =>  void
acceptIsB2(isB)
acceptIsB2(isB2)
🙁 Actual behavior

as shown in code snippet type is inferred incorrectly and I'm getting compiler error .

🙂 Expected behavior

type should be inferred correctly.

Hướng dẫn đóng góp

Mở hướng dẫn đóng góp

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Hướng nghiên cứu

Bắt đầu bằng cách chạy bản tái hiện được liên kết trong TypeScript Playground và so sánh flow(notUndefined, isB) với các đối số kiểu được cung cấp rõ ràng. Theo dõi cách các đối số generic được suy luận cho hàm tổ hợp. Hoàn thành khi mẫu suy luận kiểu trung gian mà không bao gồm undefined và biên dịch với kết quả dự kiến là "B".

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Đánh giá

Công nghệ
typescript
Lĩnh vực
compilers
Loại issue
Lỗi
Độ khó
4/5
Thời gian dự kiến
3-5 ngày
Mức độ hoạt động
Đình trệ
Độ rõ ràng
Khá rõ ràng
Mức phù hợp với người mới
45/100

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.