Тип возвращаемой функции зависит от ключа интерфейса, заданного в качестве аргумента

#typescript #types #typescript-generics #return-type

Вопрос:

У меня есть функция getThing , у которой первым аргументом должно быть имя класса в нижнем регистре, а возвращаемый тип-экземпляр самого класса или null . У него также есть второй аргумент для «поиска» класса в нем (внутренний код, здесь не важно).

Например, если я это сделаю getThing('user', "the content") , он должен вернуть меня User | null

Но я не смог найти, как это сделать, поэтому на данный момент у меня есть одна перегрузка для каждого возможного ввода, но читать ее очень долго и сложно, поэтому я спрашиваю, есть ли лучший способ сделать это ?

На данный момент у меня есть что-то подобное, но это совсем не работает :

 interface Type {
    channel: Channel;
    command: Command;
    emote: Emoji;
    guild: Guild;
    member: GuildMember;
    message: Message;
    role: Role;
    user: User;
};

async function getThing<T extends keyof Type>(datatype: T, content: string | Message): Promise<Type[typeof datatype] | null> {
    switch (dataType) {
        case 'channel':
            return new Channel();
        case 'command':
            return new Command();
        case 'emote':
            return new Emoji();
        case 'member':
            return new GuildMember();
        case 'message':
            return new Message();
        case 'role':
            return new Role();
        case 'user':
            return new User();
    }
}

async () => {
    const test = await getThing('command', 'test');
};
 

При наведении курсора на «тест» он говорит Channel | null , что правильно, но в функции все new Something() неверно , потому что TypeScript ждет Channel amp; Command amp; Emoji amp; Guild amp; GuildMember amp; Message amp; Role amp; User , а это не то, что я хочу :/

Игровая площадка TS здесь

Комментарии:

1. Я думаю, тебе придется принять участие в кастинге. Попробуй getThing<T extends keyof Type, R=Type[T]>(datatype: T, content: string | Message):Promise<R | null> , а потом return new Channel() as unknown as R

2. Попробуйте перегрузить функцию