简体   繁体   English

如何 typescript 严格键入条件 function?

[英]How to typescript strictly typed conditional function?

I am looking for real a Typescript nerd to help me with this.我正在寻找真正的 Typescript 书呆子来帮助我。 I am trying to create a function with two parameters;我正在尝试使用两个参数创建一个 function; key as the key of an interface and value as the value of the type of this key on the interface. key为接口的键, value为接口上该键的类型的值。 To constrain the types, I would like to pass as conditional type the key, so the function doesn't allow me to introduce a value with a type different than the defined to that key on the interface.为了限制类型,我想将键作为条件类型传递,因此 function 不允许我在接口上引入与该键定义的类型不同的值。 Here is an example of the approach:这是该方法的示例:

interface A {
    a: number;
    b: string;
    c: boolean;
}

function Test<T extends keyof A> (key: T, value: Pick<A, T>){

    return;

}
/* Expected results */

const res = Test<'a'>('a', 1) //ok
const res = Test<'a'>('a', true) //wrong
const res = Test<'d'>('d', true) //wrong
const res = Test<''>('', true) //display autocompletion of possible values (keys of A)

I am looking for these things:我正在寻找这些东西:

  1. Autocompletion of the available key values可用键值的自动完成
  2. That the function yells at me if I set a value with a type different than the defined for that key in interface A如果我设置的值的类型与接口 A 中为该键定义的类型不同,function 会对我大喊大叫

I accept other approaches if they are as strict as this one.如果其他方法与此方法一样严格,我接受其他方法。

Regards问候

Try using A[T] instead of Pick<A, T> .尝试使用A[T]而不是Pick<A, T>

interface A {
    a: number;
    b: string;
    c_more_to_show_autocomplete: boolean;
}

declare function Test<T extends keyof A>(key: T, value: A[T]): void;

const res = Test('a', 1) //ok
const res = Test('a', true) //wrong
const res = Test('d', true) //wrong
const res = Test('c_', true) //display autocompletion of possible values (keys of A)

TypeScript playground TypeScript操场

在此处输入图像描述

The generic described by @CameronLittle will do what you want. @CameronLittle 描述的泛型将满足您的需求。 If will infer the type of the key based on the provided string and enforce that the values match that key. If 将根据提供的字符串推断键的类型,并强制值与该键匹配。

But since you asked for a "real Typescript nerd" I feel compelled to point out that techically you can pass invalid arguments if you set the generic yourself rather than letting it be inferred.但是,既然您要求“真正的 Typescript 书呆子”,我不得不指出,从技术上讲,如果您自己设置泛型而不是让它被推断,那么从技术上讲,您可以传递无效的arguments For example:例如:

const res = Test<keyof A>('a', true);

This is not an error because 'a' is assignable to keyof A and true is assignable to A[keyof A] .这不是错误,因为'a'可分配给keyof Atrue可分配给A[keyof A] We would ideally like this to be an error since true is not assignable to A['a'] .理想情况下,我们希望这是一个错误,因为true不能分配给A['a']

The most type-safe approach is to use a union of valid pairings rather than a generic.最安全的方法是使用有效配对的联合而不是泛型。

type Args = {
    [K in keyof A]: [K, A[K]];
}[keyof A]

The above mapped type resolves to the union:上述映射类型解析为联合:

type Args = ["a", number] | ["b", string] | ["c", boolean]

These tuples are the arguments that we want Test to accept.这些元组是我们希望Test接受的 arguments。

function Test(...args: Args): void {};

This gives us proper typechecking and eliminates the possibility that we can call it invalidly.这为我们提供了正确的类型检查,并消除了我们可以无效调用它的可能性。

const res1 = Test('a', 1) //ok
const res2 = Test('a', true) //wrong
const res3 = Test('d', true) //wrong
const res4 = Test('c', true) //ok

Typescript Playground Link Typescript 游乐场链接

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM