`keyof T['prop']` becomes never when the object contains a context-sensitive function

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

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

Đánh giá

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

Hướng nghiên cứu

Bắt đầu với TypeScript Playground được liên kết và tái hiện ví dụ đệ quy Type<TAcceptedKeys, TType>. So sánh các kiểu được suy luận và chẩn đoán khi triggerFn không có tham số với khi có một tham số, đặc biệt là đối với keys và shouldBeKeyofTType. Hoàn thành có nghĩa là tham số hàm không còn làm thay đổi bất ngờ các kiểu keyof thu được.

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

Mô tả

Bug Domain: Indexed Access Types Help Wanted

Bug Report

🔎 Search Terms

Not sure how to put this but:

  • recursive type
  • function
  • parameter
  • generics
🕗 Version & Regression Information

Tested on these versions:

  • typescript@5.1.3
  • typescript@5.2.0-dev.20230716 dev
⏯ Playground Link

Playground Link

Code
type Type<
  TAcceptedKeys extends string,
  TType extends Type<TAcceptedKeys>=any
> = {
  /**
   * We're using the keys of this property, that is why
   * we use a recursive type.
   */
  obj?: Record<TAcceptedKeys, 1>
  /**
   * Just for the sake of illustration. 
   * In the circumstances of the bug this will be never[].
   */
  keys: (keyof TType['obj'])[]
  /**
   * A function with a parameter inside the recursive type.
   * This triggers the bug.
   */
  triggerFn?: (param: number) => void
  /**
   * This will always be TType, regardless of whether
   * a parameter is declared in `triggerFn` or not.
   */
  shouldBeTType?: TType
  /**
   * This will be `keyof TType` as expected if a parameter
   * is not declared in triggerFn, but it will turn to `undefined`
   * as soon as a parameter is declared in that function.
   *
   * If the below property is passed to defineType
   * the type will be as expected:
   * triggerFn: () => {}
   *
   * However this will trigger the bug:
   * triggerFn: (param) => {}
   */
  shouldBeKeyofTType?: keyof TType
}

const defineType = <TAcceptedKeys extends string>() =>
  <const TType extends Type<TAcceptedKeys, TType>>(type: TType) => type

defineType<'apple' | 'banana'>()({
  obj: {
    apple: 1,
    banana: 1
  },
  keys: [
    'apple'
  ],

  /**
   * Toggle these comments to see how the bug works.
   */
  triggerFn: () => {},      // won't produce diagnostics
  // triggerFn: (param) => {}, // type 'string' is not assignable to type 'never'

  /**
   * Toggle these comments to see diagnostics information.
   */
  // shouldBeTType: null,
  // shouldBeKeyofTType: null
})
🙁 Actual behavior

The presence or absence of a parameter in an object member function has effect on this object type in certain circumstances.

🙂 Expected behavior

It shouldn't.

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

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.

Issue khác của microsoft/TypeScript

Tất cả issue của microsoft/TypeScript

Issue tương tự

Thêm issue về Go

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.