Typescript: 如何包装接口属性?

huangapple go评论63阅读模式
英文:

Typescript: How to wrap interface properties?

问题

假设我有以下的定义:

```js
interface ISomeInterface {
  propertyA: string,
  propertyB: number,
  propertyC: boolean,
  propertyD: ISomeOtherInterface // bonus points for this one!
}

class MyGeneric<T> {}
class MyGenericContainer<T> {}

现在我想要"包装"所有属性,使得我得到类似这样的结果:

interface ISomeWrappedInterface {
  propertyA: MyGeneric<string>,
  propertyB: MyGeneric<number>,
  propertyC: MyGeneric<boolean>,
  propertyD: MyGenericContainer<ISomeOtherInterface>
}

注意:propertyD 可能是不可能的,但如果属性类型不是某种"基本"类型,我只是希望它被另一个类包装

这是我已经完成的部分:

type FromInterface<I> = ({
  [T in keyof I]: MyGeneric<typeof T>;
                                   ^--------
});

type Wrapped = FromInterface<ISomeInterface>;

但这不起作用,因为'T' only refers to a type, but is being used as a value here。我猜这是因为T在这里已经是一个类型,但显然我想要迭代的属性的"type"类型。

免责声明:我找到了这个问题,看起来类似,但实际上不是。


<details>
<summary>英文:</summary>

Suppose I have the following definitions:

```js
interface ISomeInterface {
  propertyA: string,
  propertyB: number,
  propertyC: boolean,
  propertyD: ISomeOtherInterface // bonus points for this one!
}

class MyGeneric&lt;T&gt; {}
class MyGenericContainer&lt;T&gt; {}

now I want to "wrap" all properties, so that I recieve something like that:

interface ISomeWrappedInterface {
  propertyA: MyGeneric&lt;string&gt;,
  propertyB: MyGeneric&lt;number&gt;,
  propertyC: MyGeneric&lt;boolean&gt;,
  propertyD: MyGenericContainer&lt;ISomeOtherInterface&gt;
}

Note: PropertyD is probably impossible, but in case the property type is not some "primitive", I simply want it to be wrapped by another class

This is as far as I have gotten:

type FromInterface&lt;I&gt; = ({
  [T in keyof I]: MyGeneric&lt;typeof T&gt;;
                                   ^--------
});

type Wrapped = FromInterface&lt;ISomeInterface&gt;;

But this does not work, because &#39;T&#39; only refers to a type, but is being used as a value here.
I guess it's because T already is a type here, but obviously I want the "widened" type of the property that I am iterating.

Disclaimer: I've found this question, seems similar, but isn't.

答案1

得分: 1

你可以使用以下方法:

type FromInterface<T> = {
  [K in keyof T]: T[K] extends string | number | Date
    ? MyGeneric<T[K]>
    : MyGenericContainer<T[K]>;
};

Playground链接

英文:

You can use:

  • mapped type to transform each proprerty in the input type
  • conditional type to select output property type depending on some condition
type FromInterface&lt;T&gt; = {
  [K in keyof T]: T[K] extends string | number | Date 
                  ? MyGeneric&lt;T[K]&gt; 
                  : MyGenericContainer&lt;T[K]&gt;;                            
};

Playground link

huangapple
  • 本文由 发表于 2023年3月4日 02:28:53
  • 转载请务必保留本文链接:https://go.coder-hub.com/75630665.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定