Почему Typescript пропускает / выбирает символы стирания - PullRequest
1 голос
/ 11 ноября 2019

Сначала я довольно новичок в TS. И пытаюсь поработать над некоторыми утилитами для моих собственных проектов. Но когда я работаю над отображением типов. Я обнаружил, что Pick / Omit / Exclude и другие инструкции по печати удаляют поля с символьными клавишами. как код здесь:

    interface T { a: number;[Symbol.iterator](): IterableIterator<number>; }
    type NoA=Omit<T,'a'>;

NoA будет пустой тип. Но я использую в нем итератор.

Почему это происходит? И есть ли обход?

для получения дополнительной информации, соответствующие коды в моей библиотеке:

export type Merg<U> = (U extends any ? (k: U) => void : never) extends (k: infer I) => void ? I : never;
export type MergO<U extends object> 
  = (U extends object ? (k: U) => void : never) extends 
    (k: infer I) => void ? (I extends object ? I : object) : object;

export type Alter<T extends object, U extends object> 
  = Pick<T, Exclude<keyof T, keyof U>> & Pick<U, Extract<keyof T, keyof U>>;

export type Extra<T extends object, U extends object> = Pick<T, Exclude<keyof T, keyof U>>;
export type Common<T extends object, U extends object> = Pick<T, Extract<keyof T, keyof U>>;
export type Extend<T extends object, U extends object> = T & Omit<U, keyof T>;
export type Override<T extends object, U extends object> = Omit<T, keyof U> & U;


export type AlterOver<T extends object, U extends object, X extends object> = Alter<T, Extra<U, X>>;
export type ExtendOver<T extends object, U extends object, X extends object> = Extend<T, Extra<U, X>>;
export type OverrideOver<T extends object, U extends object, X extends object> = Override<T, Extra<U, X>>;

export type AlterLike<T extends object, U extends object, X extends object> = Alter<T, Common<U, X>>;
export type ExtendLike<T extends object, U extends object, X extends object> = Extend<T, Common<U, X>>;
export type OverrideLike<T extends object, U extends object, X extends object> = Override<T, Common<U, X>>;

, основанные на обходном пути @ hackape, новое исключение по типу может быть:

export type Exclude2<T extends object, U extends object> = 
U extends { [Symbol.iterator]: any } ? Omit<T, keyof U>:
T extends { [Symbol.iterator]: infer IT } ? { [Symbol.iterator]: IT } & Omit<T, keyof U> : Omit<T, keyof U>;

1 Ответ

2 голосов
/ 11 ноября 2019

Как и @jcalz, упомянутый в комментарии, Symbol.iterator обрабатывается как «общеизвестный символ» и исключается из разрешенных отображаемых типов. В настоящее время машинописный текст видит любое выражение в форме Symbol.whatever как «общеизвестный символ».

Обходной путь:

interface T { b: boolean; a: number; [Symbol.iterator](): IterableIterator<number>; }

type Omit2<T, K extends keyof T> = T extends { [Symbol.iterator]: infer U } ? { [Symbol.iterator]: U } & Omit<T, K> : Omit<T, K>
type NoA = Omit2<T, 'a'>;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...