StackMatch
StackMatch

Reputation: 99

Exclude properties from type or interface in TypeScript for an arbitrary object

I'd like to have explicit properties excluded from type Record<string, unknown> for an input. I want to have a type used for an input.

type InputType = Omit<Record<string, unknown>, keyof AnotherType>

where AnotherType is

type AnotherType = {
    a: string;
    b: string;
    c: string;
}

How do I achieve this effect?

In essence, I want to say you can give me any object type but it should not contain these keys no matter what type of value they contain.

This InputType will be the type of an argument of a function which I will call later.

Would interfaces be a better approach here? If it can be done with generics, that would be better.

I've looked around online and here, but my vocabulary with TypeScript is a bit lacking.

The closest thing I found is this.

===EDIT===

This is what I have so far

interface AnotherType {
    a: string;
    b: string;
    c: string;
}

interface InputType extends Record<string, unknown> {
    [key: string]: any;
    a?: never;
    b?: never;
    c?: never;
}

function foo(x: InputType) {return x}

foo({
  x : 2 // fine,
  a : "a" // error,
  a : 2 // error
})

But this feels hacky, I'm repeating myself, and I'm hard coding keys.

Upvotes: 1

Views: 1836

Answers (1)

T.J. Crowder
T.J. Crowder

Reputation: 1073968

You can do that by using an intersection with mapped type mapping AnotherType's keys to the value type never (with the optional flag):

type AnotherType = {
    a: string;
    b: string;
    c: string;
}
type InputType = Record<string, unknown> & {
    [key in keyof AnotherType]?: never;
    // −−−−−−−−−−−−−−−−−−−−−−−^−−^^^^^^−−−−− optional and never
};

const x: InputType = {
    q: 42,  // <=== Okay
    a: 42,  // <=== Error
};

function example(x: InputType) {
    console.log(x);
}

example({
    q: 42,  // <=== Okay
    a: 42,  // <=== Error
});

declare let arg1: {q: number};
declare let arg2: {a: number};

example(arg1);  // <=== Okay
example(arg2);  // <=== Error

Playground link

Upvotes: 1

Related Questions