Typescript TS条件类型仅扩展联合中的一个项
我希望创建一个函数,它接受来自接口Typescript TS条件类型仅扩展联合中的一个项,typescript,Typescript,我希望创建一个函数,它接受来自接口Foo的键作为输入,仅限于Foo的键,而string是可接受的赋值 interface Foo { a: string; b?: string; c?: string | boolean; } test("a"); test("b"); // Argument of type '"b"' is not assignable to parameter of type 'never'.ts(2345) test("c"); // Argument of
Foo
的键作为输入,仅限于Foo
的键,而string
是可接受的赋值
interface Foo {
a: string;
b?: string;
c?: string | boolean;
}
test("a");
test("b"); // Argument of type '"b"' is not assignable to parameter of type 'never'.ts(2345)
test("c"); // Argument of type '"c"' is not assignable to parameter of type 'never'.ts(2345)
function test<K extends keyof Foo>(key: Foo[K] extends string ? K : never) {}
接口Foo{
a:弦;
b:字符串;
c?:字符串|布尔值;
}
测试(“a”);
测试(“b”);//类型为“b”的参数不能分配给类型为“never”的参数。ts(2345)
测试(“c”);//类型为“c”的参数不能分配给类型为“never”的参数。ts(2345)
函数测试(key:Foo[K]扩展字符串?K:never){}
对于b
和c
,上述(严格模式打开时)失败-是否有方法使用扩展字符串
(或类似)
不必精确匹配属性的类型?我对其他可能的类型不感兴趣,只是类型可能是
字符串
所以,您显然要寻找的测试是string extensed Foo[K]
,而不是Foo[K]extensed string
:
function test<K extends keyof Foo>(key: string extends Foo[K] ? K : never) {}
test("a"); // okay
test("b"); // okay
test("c"); // okay
interface Foo {
e: "specificString";
}
test("e"); // error!
// Argument of type '"e"' is not assignable to parameter of type 'never'.
并且它拒绝比字符串
窄的类型的属性:
function test<K extends keyof Foo>(key: string extends Foo[K] ? K : never) {}
test("a"); // okay
test("b"); // okay
test("c"); // okay
interface Foo {
e: "specificString";
}
test("e"); // error!
// Argument of type '"e"' is not assignable to parameter of type 'never'.
您无法为任何旧字符串s
编写foo.e=s
,因此这是拒绝的原因。(如果你需要接受这一点,那么你是在要求更复杂的东西来表达,而且也不清楚为什么需要这样做……因为在这种情况下,你既不能读也不能写字符串
值)
还要注意,
test
似乎不需要是泛型的。。。您可以创建一个泛型类型别名,如:
type KeysAssignableFrom<T, V> = {
[K in keyof T]-?: V extends T[K] ? K : never
}[keyof T];
这相当于:
// function testConcrete(key: "a" | "b" | "c"): void
好吧,希望这会有帮助;祝你好运
string extensed Foo[K]
就是你的意思,而不是Foo[K]extensed string
@jcalz取决于他是否希望包含字符串文字类型。@jcalz好吧,这确实解决了这个问题,哈哈。你能解释一下区别吗?