58
задан 14 February 2019 в 14:14

2 ответа

type ModifiedType = Modify<OriginalType, {
  a: number;
  b: number;
}>

Вдохновленный ZSkycat's extends Omit решение, я придумал это:

type Modify<T, R> = Omit<T, keyof R> & R;

// before typescript@3.5
type Modify<T, R> = Pick<T, Exclude<keyof T, keyof R>> & R

Пример:

interface OriginalType {
  a: string;
  b: boolean;
  c: number;
}

type ModifiedType  = Modify<OriginalType , {
  a: number;
  b: number;
}>

// ModifiedType = { a: number; b: number; c: number; }

Движение шаг за шагом:

type R0 = Omit<OriginalType, 'a' | 'b'>        // { c: number; }
type R1 = R0 & {a: number, b: number }         // { a: number; b: number; c: number; }

type T0 = Exclude<'a' | 'b' | 'c' , 'a' | 'b'> // 'c'
type T1 = Pick<OriginalType, T0>               // { c: number; }
type T2 = T1 & {a: number, b: number }         // { a: number; b: number; c: number; }

Типы Утилиты TypeScript

35
ответ дан 1 November 2019 в 13:25

Расширяя ответ @zSkycat немного, можно создать дженерик, который принимает два типов объектов и возвращает объединенный тип с участниками второго переопределения членов первого.

type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>
type Merge<M, N> = Omit<M, Extract<keyof M, keyof N>> & N;

interface A {
    name: string;
    color?: string;
}

// redefine name to be string | number
type B = Merge<A, {
    name: string | number;
    favorite?: boolean;
}>;

let one: A = {
    name: 'asdf',
    color: 'blue'
};

// A can become B because the types are all compatible
let two: B = one;

let three: B = {
    name: 1
};

three.name = 'Bee';
three.favorite = true;
three.color = 'green';

// B cannot become A because the type of name (string | number) isn't compatible
// with A even though the value is a string
// Error: Type {...} is not assignable to type A
let four: A = three;
25
ответ дан 1 November 2019 в 13:25

Другие вопросы по тегам:

Похожие вопросы: