1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
|
=== tests/cases/compiler/complicatedIndexedAccessKeyofReliesOnKeyofNeverUpperBound.ts ===
interface TextChannel {
id: string;
>id : string
type: 'text';
>type : "text"
phoneNumber: string;
>phoneNumber : string
}
interface EmailChannel {
id: string;
>id : string
type: 'email';
>type : "email"
addres: string;
>addres : string
}
type Channel = TextChannel | EmailChannel;
>Channel : TextChannel | EmailChannel
export type ChannelType = Channel extends { type: infer R } ? R : never;
>ChannelType : "text" | "email"
>type : R
type Omit<T, K extends keyof T> = Pick<
>Omit : Omit<T, K>
T,
({ [P in keyof T]: P } & { [P in K]: never } & { [x: string]: never })[keyof T]
>x : string
>;
type ChannelOfType<T extends ChannelType, A = Channel> = A extends { type: T }
>ChannelOfType : ChannelOfType<T, A>
>type : T
? A
: never;
export type NewChannel<T extends Channel> = Pick<T, 'type'> &
>NewChannel : NewChannel<T>
Partial<Omit<T, 'type' | 'id'>> & { localChannelId: string };
>localChannelId : string
export function makeNewChannel<T extends ChannelType>(type: T): NewChannel<ChannelOfType<T>> {
>makeNewChannel : <T extends "text" | "email">(type: T) => NewChannel<ChannelOfType<T>>
>type : T
const localChannelId = `blahblahblah`;
>localChannelId : "blahblahblah"
>`blahblahblah` : "blahblahblah"
return { type, localChannelId };
>{ type, localChannelId } : { type: T; localChannelId: string; }
>type : T
>localChannelId : string
}
const newTextChannel = makeNewChannel('text');
>newTextChannel : NewChannel<TextChannel>
>makeNewChannel('text') : NewChannel<TextChannel>
>makeNewChannel : <T extends "text" | "email">(type: T) => NewChannel<ChannelOfType<T, TextChannel> | ChannelOfType<T, EmailChannel>>
>'text' : "text"
// This should work
newTextChannel.phoneNumber = '613-555-1234';
>newTextChannel.phoneNumber = '613-555-1234' : "613-555-1234"
>newTextChannel.phoneNumber : string
>newTextChannel : NewChannel<TextChannel>
>phoneNumber : string
>'613-555-1234' : "613-555-1234"
const newTextChannel2 : NewChannel<TextChannel> = makeNewChannel('text');
>newTextChannel2 : NewChannel<TextChannel>
>makeNewChannel('text') : NewChannel<TextChannel>
>makeNewChannel : <T extends "text" | "email">(type: T) => NewChannel<ChannelOfType<T, TextChannel> | ChannelOfType<T, EmailChannel>>
>'text' : "text"
// Compare with this, which ofc works.
newTextChannel2.phoneNumber = '613-555-1234';
>newTextChannel2.phoneNumber = '613-555-1234' : "613-555-1234"
>newTextChannel2.phoneNumber : string
>newTextChannel2 : NewChannel<TextChannel>
>phoneNumber : string
>'613-555-1234' : "613-555-1234"
|