打字稿动态字符串联合

时间:2019-12-09 17:10:33

标签: typescript

我需要动态地将字符串类型相交,如下所示。

export class Foo<K extends string> {
    addKey<L extends string>(key: L): Foo<K | L> {
        return this;
    }
    getKey(key: K) {

    }
}

const x = new Foo().addKey('a').addKey('b');

// need to constraint this to 'a' | 'b'
x.getKey('')

http://www.typescriptlang.org/play/?ssl=1&ssc=1&pln=13&pc=13#code/KYDwDg9gTgLgBAYwDYEMDOa4DEIQDwDScoMwAdgCaZoxQCWZA5gHxwDeAUHN3ChRQWABPPABliIUpWq0GLABQBrYQC44ogJRqc+IgB91rTjxNwowGAFcoZODAAWdNAG4uPAL5vujC4KFLVOAINdg4vOE9PDgQIMho4EDgAXjgyYAB3bFx5DQA6PgFheQByFGK8gr8SgCNy1w4AegbU4GAKOwhEWJooFAZ4BycOuFLiuANi2o4QXJ8YKuLyoA

2 个答案:

答案 0 :(得分:2)

大概您的问题是int main ( int argc , char * argv []) { int fd [2]; if ( argc != 4) exit (1); pipe (fd ); if ( fork () == 0) { dup2 (fd [1] , 1); execlp ( argv [1] , argv [1] , NULL ); } else { close (fd [1]); dup2 (fd [0] , 0); close (1); open ( argv [3] , O_WRONLY | O_TRUNC | O_CREAT , 0600); execlp ( argv [2] , argv [2] , NULL ); wait ( NULL ); } exit (0); } 生成new Foo()的实例,而absorbsFoo<string> string literal types则通过union加入时生成。也就是说,string只是string | "a" | "b",这完全忘记了string"a"”。

这里需要做的就是为"b选择一个default值,以便它表示任何字符串的缺乏。某些类型扩展了K但没有值,因此当您将string加入到一个联合中时,您会得到"a"。幸运的是,该类型存在,它称为never。作为bottom type的情况,"a"扩展了包括never在内的所有类型,并且在通过并集加入时被其他所有类型吸收。因此string将是never | "a" | "b"

在这里:

"a" | "b"

让我们对其进行测试:

export class Foo<K extends string = never> { // K has a default now
    addKey<L extends string>(key: L): Foo<K | L> {
        return this;
    }
    getKey(key: K) {

    }
}

对我很好。希望能有所帮助;祝你好运!

Link to code

答案 1 :(得分:1)

有几种方法可以破解这个鸡蛋

通常,我会为要用作联合的字符串子集定义类型别名。

export class Foo<K extends string> {
    // note L extending K here, you may want to do it the other way
    addKey<L extends K>(key: L): Foo<K | L> {
        return this;
    }
    getKey(key: K) {

    }
}

type StringAlias = 'a' | 'b'
// Now all are constrained
const x = new Foo<StringAlias>().addKey('b').addKey('a');
x.getKey('a')