microsoft / microsoft/TypeScript
"Lookup" Type Broken When Using Generics
Chưa có ai nhận issue này.
- Ngôn ngữ chính
- Go
- Star
- 111k
- Fork
- 14.3k
- Merge trung bình
- 2 ngày 4 giờ
- Pull request đã merge (30 ngày)
- 132
Mô tả
🔎 Search Terms
"nested lookup with generic", "type lookup with generic"
🕗 Version & Regression Information
- For
doesNotWork1, this changed between versions3.9.7and4.0.5. - For other "not working" examples, this is the behavior in every version I tried, and I reviewed the FAQ for entries about generics within lookup tables.
⏯ Playground Link
💻 Code
interface WithCommon {
field1: number;
field2: string;
}
interface WithSpecial extends WithCommon {
special: number;
}
interface SpecialLookup {
special: WithSpecial;
}
interface CommonLookup extends SpecialLookup {
common: WithCommon;
}
type Lookup<Name extends keyof CommonLookup> = {
[K in keyof CommonLookup[Name]]?: CommonLookup[Name][K];
};
// NOTE: this is broken even with `keyof CommonLookup` — key `special` has to be removed to see current error return since with `CommonLookup` we do detect that `special` is not a shared key of all members
function someName<K extends keyof SpecialLookup>(): void {
const works1: Lookup<'special'> = {
field1: 1,
field2: 'common',
special: 203,
};
const works2: Lookup<'common'> = {
field1: 5,
field2: 'something',
// correctly finds that this field should not be there
special: 32,
};
// expectation is that `undefined` should be allowed due to property types showing that it should be
// NOTE: this *was* working in v3.9.7
const doesNotWork1: Lookup<K> = {
// (property) special?: CommonLookup[K]["special"] | undefined — so at minimum this should be resolve to `undefined` since `never | undefined` resolves to `undefined`...
special: undefined,
field1: undefined,
field2: undefined,
};
// expectation is that this would be able to correctly identify fields in common for this specific set of keys
// NOTE: this does not work in any version available in playground
const doesNotWork2: Lookup<K> = {
special: 1004,
}
// expectation is that this would be able to correctly identify fields in common with all examples
// NOTE: this does not work in any version available in playground
const doesNotWork3: Lookup<K> = {
field1: 15,
field2: 'another'
}
}
🙁 Actual behavior
When using a generic as the input to a "lookup" type, we should be able to correctly type the common fields of the "looked-up" interfaces.
What is interesting here is that we appear to get correct behavior from "code completion" (i.e. special is correctly typed as a property of Lookup<K> with type CommonLookup[K]["special"] | undefined), but actually setting the presented type value doesn't work.
🙂 Expected behavior
We should get correct typing for the generic Lookup<K> type:
doesNotWork1should allowundefinedas a value since field type evaluates toCommonLookup[K][Field] | undefined.doesNotWork2should allownumberas value for fieldspecialsince all interfaces withinkeyof SpecialLookuphavespecial: numberon the interface.doesNotWork3should allow values forfield1andfield2for the same reason asdoesNotWork2.
Additional information about the issue
As I called out in my NOTE within the code example, this is also broken in a "simpler" example where the generic is K extends keyof CommonLookup. I presented the above code example because it is the most similar to my use case and I wasn't sure if fixing the "simpler" case would also fix the one where we are choosing a smaller key set.
Hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- 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.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Hướng nghiên cứu
Bắt đầu với TypeScript Playground được liên kết và tái hiện các ví dụ doesNotWork1–3 trên các phiên bản trình biên dịch đã nêu. Theo dõi hành vi kiểm tra kiểu của generic lookup, sau đó xác minh rằng các phép gán undefined và các trường chung như mong đợi đều được kiểm tra kiểu mà không cho phép các trường không hợp lệ.
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ó
- 5/5
- Thời gian dự kiến
- Hơn một tuần
- Mức độ hoạt động
- Đình trệ
- Độ rõ ràng
- Đặc tả rõ ràng
- Mức phù hợp với người mới
- 35/100