Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在typescript中扩展联合类型别名?_Typescript - Fatal编程技术网

在typescript中扩展联合类型别名?

在typescript中扩展联合类型别名?,typescript,Typescript,我试图在编译时将一些字符串字段限制为只有某些值。问题是这些值应该是可扩展的。 下面是一个简化的示例: type Foobar = 'FOO' | 'BAR'; interface SomeInterface<T extends Foobar> { amember: T; [key: string]: string; // this really has to stay } // let's test it const yes = { amember: 'FOO

我试图在编译时将一些字符串字段限制为只有某些值。问题是这些值应该是可扩展的。 下面是一个简化的示例:

type Foobar = 'FOO' | 'BAR';

interface SomeInterface<T extends Foobar> {
  amember: T;

  [key: string]: string; // this really has to stay
}

// let's test it

const yes = {
    amember: 'FOO'
} as SomeInterface<'FOO'>; // compiles as expected

//    const no = {
//        amember: 'BAZ'
//    } as SomeInterface<'BAZ'>; // Type '"BAZ"' does not satisfy the constraint 'Foobar' as expected

// so far so good
// Now the problem

abstract class SomeClass<T extends Foobar> {
  private anotherMember: SomeInterface<T>;
}

type Foobarbaz = Foobar | 'BAZ';

class FinalClass extends SomeClass<Foobarbaz> { //no good anymore
}
type Foobar='FOO'|'BAR';
接口接口{
成员:T;
[key:string]:string;//这真的必须保持下去
}
//让我们测试一下
常数是={
成员:“FOO”
}作为接口;//按预期编译
//常数编号={
//amember:'BAZ'
//}作为SomeInterface;//类型“BAZ”不满足预期的约束“Foobar”
//到目前为止还不错
//现在问题来了
抽象类{
私有anotherMember:SomeInterface;
}
类型Foobarbaz=Foobar |“BAZ”;
类FinalClass扩展了一些类{//不再有用了
}
错误是

类型“Foobarbaz”不满足约束“Foobar”。类型 “BAZ”不可分配给类型“Foobar”

所以问题是:在typescript中,如何将“type”限制为只包含某些字符串,但可以用其他字符串扩展? 或者这是一个XY问题,并且有一个明显更好的解决方案

Typescript 2.3.4,但我认为如果有魔力的话,我可以升级到2.4

在typescript中,如何将“type”限制为仅包含某些字符串,但可以与其他字符串一起扩展

不知道您的X问题是什么,但您始终可以引入另一个泛型参数,并通过声明扩展该参数来限制类型。键入脚本2.3,因此默认情况下,您可以像以前一样使用带有一个参数的
SomeInterface
,当您需要它来扩展其他内容时,您可以显式提供:

type Foobar = 'FOO' | 'BAR';

interface SomeInterface<T extends X, X extends string=Foobar> {
  amember: T;

  [key: string]: string; // this really has to stay
}

// let's test it

const yes = {
    amember: 'FOO'
} as SomeInterface<'FOO'>; // compiles as expected


abstract class SomeClass<T extends X, X extends string=Foobar> {
  private anotherMember: SomeInterface<T, X>;
}

type Foobarbaz = Foobar | 'BAZ';

class FinalClass extends SomeClass<Foobarbaz, Foobarbaz> { 
}

我认为您使用的“可扩展”一词的含义与关键字
extends
的含义不同。如果说该类型是“可扩展的”,则表示希望能够扩展该类型以接受更多值。但是当某个
扩展了一个类型时,这意味着您正在缩小该类型以接受更少的值

SomeInterface
基本上只能是以下四种类型之一:

  • SomeInterface
    amember
    可以是
    'FOO'
    'BAR'
  • SomeInterface
    amember
    只能是
    “FOO”
  • SomeInterface
    amember
    只能是
    'BAR'
  • SomeInterface
    amember
    不能接受任何值
我有点怀疑这是你真正想要的,但只有你能确定


另一方面,如果您想定义
SomeInterface
,使
T
始终可以是
FOO
BAR
,但也可能是一些其他
字符串
值,那么您需要的是TypeScript不完全提供的内容,这将为
T
指定一个下限。类似于
SomeInterface
,它不是有效的TypeScript

但是您可能只关心
amember
的类型,而不关心
T
。如果希望
amember
FOO
BAR
,但也可能是其他一些
字符串
值,可以如下指定:

interface SomeInterface<T extends string = never> {
  amember: Foobar | T;
  [key: string]: string; 
}


我回答你的问题了吗?希望对您有所帮助。

要实现您需要的功能,您可以通过
&
符号使用

type Foobar = 'FOO' | 'BAR';
type FoobarBaz = Foobar | & 'BAZ'; // or: 'BAZ' | & Foobar

问题中的X是这样的:基类应该只能对任何Foobar操作,而子类可能有其他值。这里有一个扩展:注释中的格式很难设置,所以我最终选择了@jcalz,这就是为什么我将它标记为正确的。您的操作也是正确的,而且对于操作员的
键来说是额外的荣誉。是的,这似乎解决了问题。唯一纯粹的担忧是
amember:Foobar|T读起来像T可以是任何东西,而不是Foobar的后代。但那是个小调。我想你是对的,因为缺少了
super
。pretier会去掉额外的
&
。你能链接这个技巧的来源吗?@jayarjo有一个链接,指向交叉点类型的文档(现在已弃用)。但是我找不到任何最新的文档。
const yes = {
    amember: 'FOO'
} as SomeInterface; // good, 'FOO' is a Foobar

const no = {
    amember: 'BAZ'
} as SomeInterface; // bad, 'BAZ' is not a Foobar

abstract class SomeClass<T extends string> {
  private anotherMember: SomeInterface<T>;
}

class FinalClass extends SomeClass<'BAZ'> { 
} // fine, we've added 'BAZ'

// let's make sure we did:
type JustChecking = FinalClass['anotherMember']['amember']
// JustChecking === 'BAZ' | 'FOO' | 'BAR'
type Foobar = 'FOO' | 'BAR';
type FoobarBaz = Foobar | & 'BAZ'; // or: 'BAZ' | & Foobar