2017-09-20 8 views
2

私はprotertyは活字体で、いくつかの性質を持っていないインタフェースを定義する方法childrenTypeScriptにいくつかのプロパティを持たないインターフェイスを定義する方法は?

type ChildrenType = Array<number> 
interface ProptyDontHaveChildren { 
    // doesn't have property called children 
    [index: string]: string; 
} 
interface WithChildren { 
    children: ChildrenType 
} 
type IntersectionType = ProptyDontHaveChildren & WithChildren; 

function createElement(type: string, props: ProptyDontHaveChildren, ...children: ChildrenType) { 
    const newProps:IntersectionType = { children: children, ...props } 
    //TODO ... 
} 

呼ばれていていないProptyDontHaveChildrenと呼ばれるインタフェースを記述したいですか?

+0

できません。 newPropsを作成する前に、あるいは 'newProps = {... props};を作成する前に、どのように' props ['children'] 'を削除してください。 newProps.children = children'? –

答えて

2

かなりの数の問題がここにあります。警告される:


あなたはProptyDontHaveChildrenタイプneverまたはundefinedchildrenオプションのプロパティを作ることができる(これは、プロパティがオプションであることが重要です):

type ChildrenType = Array<number> 
interface ProptyDontHaveChildren { 
    [index: string]: string; 
    children?: never; // note the ? 
} 

ProptyDontHaveChildrenからのみ作成することができることを保証します不足または定義されていないものがあります。children


しかし、今の交差点 IntersectionTypeあなたが望むものではありません。タイプ undefinedのと種類 ChildrenTypeの両方のこと children交差点の需要は、起こることができないので、それはまた childrenを持つことはできません。

let oops: IntersectionType = { children: [1, 2, 3] } // error 
あなたは、あなたが何を望むか( ProptyHaveChildrenを定義することができるように

はこれを行うには最善のことは、基本Proptyタイプの交差点とWithoutChildrenタイプとしてProptyDontHaveChildrenを定義することですIntersectionType)は、ProptyWithChildrenの交点になります。このように:

interface Propty { 
    [index: string]: string; 
} 
interface WithoutChildren { 
    children?: never 
} 
interface WithChildren { 
    children: ChildrenType 
} 
type ProptyDontHaveChildren = Propty & WithoutChildren 
type ProptyHaveChildren = Propty & WithChildren 

しかし、まだ問題があります。 ProptyHaveChildrenタイプは、childrenのプロパティを持つことはできません。インデックスシグネチャでは、のタイプのchildrenを含む)が必要になるためです。だから、childrenが起こることができないnumberstringと配列の両方でなければなりません:私はここから

const proptyHaveChildren: ProptyHaveChildren = { 
    a: "a", 
    children: [1, 2, 3] 
}; // error! 

function createElement(type: string, props: ProptyDontHaveChildren, ...children: ChildrenType) { 
    // error! 
    const newProps:ProptyHaveChildren = { children: children, ...props } 
} 

続行したいかどうかはわかりません。 TypeScriptにはがありません。つまり、インデックス署名はキーを指す必要があります。"children"以外のものを指定する必要があります。すべてのプロパティがあるように、あなたはProptyタイプを開くことができいずれかstringnumberの配列:

const proptyHaveChildren: ProptyHaveChildren = { 
    a: [1, 2, 3], 
    children: [1, 2, 3] 
}; // no error! 

:動作しますが、今はすべてのプロパティがnumbersの配列を受け入れます

interface Propty { 
    [index: string]: string | ChildrenType; 
} 

function createElement(type: string, props: ProptyDontHaveChildren, ...children: ChildrenType) { 
    // no error 
    const newProps:ProptyHaveChildren = { children: children, ...props } 
} 

それはおそらくあなたが望むものではありません。


この時点で、私はあなたのインターフェイスを理解するためにTypeScriptと戦っていることに気付いています。たぶん行うための最善のことは、それは2つのプロパティが含まれるようにProptyのあなたの表現を変更することです:すべてのものをstringの特性、およびchildren保持するpropsプロパティ:

type ChildrenType = Array<number> 

interface Propty { 
    props: { [index: string]: string } 
} 
interface WithoutChildren { 
    children?: never 
} 
interface WithChildren { 
    children: ChildrenType 
} 
type ProptyDontHaveChildren = Propty & WithoutChildren 
type ProptyHaveChildren = Propty & WithChildren 

const proptyHaveChildren: ProptyHaveChildren = { props: { a: "a" }, children: [1, 2, 3] }; // works 

function createElement(type: string, props: ProptyDontHaveChildren, ...children: ChildrenType) { 
    const newProps: ProptyHaveChildren = { children: children, props: props.props } // works 
} 

は今、活字体は理解し、すべてが動作します...あなたのタイプを複数のサブプロパティに分割するのを犠牲にしてください。元の構造を好むかもしれません。あなたが上記の問題に対処するのに十分なのかどうかは、あなた次第です。


希望します。がんばろう!

+0

ありがとうございます。 – xiang

1

あなたはchildrenProptyDontHaveChildren上に存在してはならないことを示すためにタイプneverを使用することができます。

type ChildrenType = Array<number> 
interface ProptyDontHaveChildren { 
    [index: string]: string; 
    children: never; 
} 
interface WithChildren { 
    children: ChildrenType 
} 
type IntersectionType = ProptyDontHaveChildren & WithChildren; 

function createElement(type: string, props: ProptyDontHaveChildren, ...children: ChildrenType) { 
    // OK. No error 
    const newProps:IntersectionType = { children: children, ...props } 
} 
+0

残念ながら、上記のタイプのインスタンスを作成しようとすると明らかになる、このソリューションに問題があります。詳細については、[my answer](https://stackoverflow.com/a/46322516/2887218)を参照してください。 – jcalz

関連する問題