Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
159 views
in Technique[技术] by (71.8m points)

TypeScript: Define a sub-type explicitly

Given type A, I want to define a sub-type B (B is assignable to A, without extra properties) and enforce that assign-ability.

Example

Given this type:

interface A {
  name?: string;
  age?: number;
}

I want to define this type:

interface B {
  name: string;
}

As you can see, any instance of PersonDescriptor is assignable to Person, but it is not enforced. If I add another property, I would like typescript to complain.

Unacceptable solutions

  1. I cannot use extend, since it will the resulted type will be less strict than what I intend:
interface B extends A {
  name: string;
}

Is equivalent to:

interface B {
  name: string;
  age?: number;
}

And also I can add properties that does not exist on Person.

  1. I cannot do A extends B since A is already provided, and B is the type I want to create.
question from:https://stackoverflow.com/questions/65871144/typescript-define-a-sub-type-explicitly

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Since you only want fields that already exist in A, you should consider using another approach, e.g.:

type IsAssignable<X, Y extends X> = {
  [K in keyof Y]: K extends keyof X ? Y[K] : never;
}

type B = IsAssignable<A, { name: string; }>;

This wouldn't stop you from declaring

type C = IsAssignable<A, {
  name: string;
  foo: number;
}>;

// C becomes { name: string; foo: never }

But it's still type-safe! Essentially, IsAssignable<X,Y> is telling typescript to ignore fields that aren't present in X. So any function that expects A should still accept C gladly;


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...