我试图在编译时将某些字符串字段限制为仅某些值.问题是这些值应该是可扩展的.这是一个简化的例子:
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
}
Run Code Online (Sandbox Code Playgroud)
错误是
类型'Foobarbaz'不满足约束'Foobar'.类型'"BAZ"'不能分配给'Foobar'类型.
所以问题是:在打字稿中我如何才能将'type'限制为仅限某些字符串,但是可以使用其他字符串扩展吗?或者这是一个XY问题,有一个明显更好的解决方案?
打字稿2.3.4但我认为如果那里有魔力我可以升级到2.4.
jca*_*alz 12
我认为你在与关键字的extends含义不同的意义上使用"可扩展"这个词.按说类型是"可扩展"你说你想成为能够扩大类型接受更多的价值.但是当某种extends类型的东西时,它意味着你缩小类型以接受更少的值.
SomeInterface<T extends Foobar> 基本上只能是以下四种类型中的一种:
SomeInterface<'FOO'|'BAR'>:amember可以是'FOO'或'BAR'SomeInterface<'FOO'>:amember可以只'FOO'SomeInterface<'BAR'>:amember可以只'BAR'SomeInterface<never>:amember不能采取任何价值我有点怀疑这实际上是你想要的,但只有你肯定知道.
在另一方面,如果你想SomeInterface<T>进行定义,从而T可以始终是无论是FOO或BAR,但也可能是一些其他的string价值,你想要的东西,打字稿不完全提供,这将指定一个下界T.类似的东西,这是无效的TypeScript.SomeInterface<TsuperFoobar extends string>
但你可能只关心它的类型amember,而不是T.如果你想amember成为或者,FOO或者BAR也可能是其他一些string值,你可以像这样指定它:
interface SomeInterface<T extends string = never> {
amember: Foobar | T;
[key: string]: string;
}
Run Code Online (Sandbox Code Playgroud)
T你想要允许的额外文字的联合在哪里.如果你不想允许任何额外的,使用never,或者只是省略type参数(因为我把它never作为默认值).
让我们看看它的实际效果:
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'
Run Code Online (Sandbox Code Playgroud)
我回答你的问题了吗?希望有所帮助.
为了实现您的需要,您可以通过符号使用交集&。
type Foobar = 'FOO' | 'BAR';
type FoobarBaz = Foobar | & 'BAZ'; // or: 'BAZ' | & Foobar
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3832 次 |
| 最近记录: |