如何定义不使用';TypeScript中没有某些属性?

如何定义不使用';TypeScript中没有某些属性?,typescript,Typescript,我想编写一个名为ProptyDontHaveChildren的接口,它没有名为children的proerty type ChildrenType = Array<number> interface ProptyDontHaveChildren { // doesn't have property called children [index: string]: string; } interface WithChildren { children: Chi

我想编写一个名为
ProptyDontHaveChildren
的接口,它没有名为
children的proerty

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 ...
}
type ChildrenType=Array
儿童的接口属性{
//没有名为children的属性
[索引:字符串]:字符串;
}
与儿童的接口{
儿童:儿童类型
}
类型IntersectionType=ProptyDontHaveChildren&WithChildren;
函数createElement(类型:string,props:ProptyDontHaveChildren,…children:ChildrenType){
const newProps:IntersectionType={children:children,…props}
//待办事项。。。
}
如何定义在TypeScript中没有某些属性的接口?

您可以使用该类型指示
子对象不应存在于
属性的子对象上:

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 }
}
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
}
type ChildrenType=Array
儿童的接口属性{
[索引:字符串]:字符串;
儿童:从不;
}
与儿童的接口{
儿童:儿童类型
}
类型IntersectionType=ProptyDontHaveChildren&WithChildren;
函数createElement(类型:string,props:ProptyDontHaveChildren,…children:ChildrenType){
//好的,没有错
const newProps:IntersectionType={children:children,…props}
}

这里有很多问题。请注意:


您可以在
ProptyDontHaveChildren
中将
children
设置为类型为
never
undefined
的可选属性(属性必须是可选的):

因此,最好的做法是将
ProptyDontHaveChildren
定义为基本
Propty
类型和无子类型的
的交叉点,这样您就可以定义
ProptyHaveChildren
(您想要的
IntersectionType
)作为
Propty
与孩子的交集
。像这样:

interface Propty  {
    [index: string]: string;
}
interface WithoutChildren {
    children?: never
}
interface WithChildren {
    children: ChildrenType 
}
type ProptyDontHaveChildren = Propty & WithoutChildren
type ProptyHaveChildren = Propty & WithChildren
但还是有一个问题。
ProptyHaveChildren
类型仍然不能具有类型为
children
的属性,因为索引签名要求每个属性(包括
children
)都是类型为
string
。因此
子项
必须既是
字符串
又是
数字
数组,这是不可能发生的:

let oops: IntersectionType = { children: [1, 2, 3] } // error
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”
。您可以打开
属性
类型,使每个属性都是
字符串
数字
的数组:

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

function createElement(type: string, props: ProptyDontHaveChildren, ...children: ChildrenType) {
    // no error
    const newProps:ProptyHaveChildren = { children: children, ...props }
}
这是可行的,但现在每个属性都将接受一个
数字数组

const proptyHaveChildren: ProptyHaveChildren = { 
  a: [1, 2, 3], 
  children: [1, 2, 3] 
}; // no error!
那可能不是你想要的


在这一点上,我注意到我正在使用TypeScript来迫使它理解您的界面。也许最好的做法是更改
Propty
的表示形式,使其包含两个属性:一个
props
属性用于保存所有
字符串
属性,另一个
子属性

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 }
}
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
}
type ChildrenType=Array
界面属性{
道具:{[index:string]:string}
}
无子接口{
孩子?:从来没有
}
与儿童的接口{
儿童:儿童类型
}
键入ProptyDontHaveChildren=Propty&无子项
键入ProptyHaveChildren=Propty&WithChildren
const proptyHaveChildren:proptyHaveChildren={props:{a:'a'},children:[1,2,3]};//作品
函数createElement(类型:string,props:ProptyDontHaveChildren,…子项:ChildrenType){
const newProps:ProptyHaveChildren={children:children,props:props.props}//works
}
现在TypeScript明白了,一切正常。。。以将类型拆分为多个子属性为代价。你可能更喜欢你原来的结构。这取决于你是否愿意处理上述问题



希望有帮助。祝你好运

不能;如何
在创建新道具之前删除道具['children']
,甚至简单地说:
newProps={…props};newProps.children=children
?不幸的是,此解决方案存在问题,当您尝试创建上述类型的实例时,这些问题变得很明显。有关更多信息,请参阅。