【问题标题】:How to define type as a list of object keys defined like [key: string] key/value structure - TypeScript如何将类型定义为定义为 [key: string] 键/值结构的对象键列表 - TypeScript
【发布时间】:2021-03-16 18:42:52
【问题描述】:

我想像这样在 TypeScript 中定义接口,但我不知道该怎么做:

export interface SomeInterface {
  testProp:{
  [key: string]: {
    prop1: string;
    prop2?: string;
    prop3?: string;
    ....

  };
}
  requiredProps: ???? // <- here i would like to define type to be array of used keys
}

例如对象:

 const value = {
    testProp: {
      orange: {
        prop1: 'test1',
      },
      kiwi: {
        prop1: 'random text',
      },
      lemon: {
        prop1: 'text',
      },
    },
   requiredProps: [] // posible items in array "lemon", "kiwi", "orange"
  };

我尝试将 requiredProps 定义为 requiredProps: [keyof Pick&lt;SomeInterface,"testProp"] 但没有成功

【问题讨论】:

    标签: typescript typescript-typings typescript2.0 typescript-generics


    【解决方案1】:

    没有与您尝试执行的操作相对应的特定类型。但是,您可以将其表示为 generic 类型。例如:

    export interface SomeInterface<K extends PropertyKey, R extends K> {
        testProp: Record<K, {
            prop1: string;
            prop2?: string;
            prop3?: string;
        }>;
        requiredProps: R[]
    }
    

    这将按照您想要的方式限制事物,但是为了创建 SomeInterface 类型的值,您需要指定 KR 参数。您可以让编译器通过辅助函数推断那些:

    const asSomeInterface = <K extends PropertyKey, R extends K>(x: SomeInterface<K, R>) => x;
    

    并像这样使用它:

    const value = asSomeInterface({
        testProp: {
            orange: {
                prop1: 'test1',
            },
            kiwi: {
                prop1: 'random text',
            },
            lemon: {
                prop1: 'text',
            },
        },
        requiredProps: ["orange", "kiwi"]
    });
    

    当您向requiredProps 添加不是testProp 的键的元素时,您会看到所需的错误:

    asSomeInterface({
        testProp: {
            a: { prop1: "" }, b: { prop1: "" }, c: { prop1: "" }
        },
        requiredProps: ["a", "b", "c", "d"] // error!
        // --------------------------> ~~~~
        // Type '"d"' is not assignable to type '"a" | "b" | "c"'
    })
    

    使SomeInterface&lt;K, R&gt; 成为泛型类型更加复杂,因为任何处理它们的值或函数都需要携带额外的类型参数。您可能会考虑只对公开给无法保证输入正确的外部用户的代码使用泛型,然后在内部将类型扩展为安全性较低但更容易传递的非泛型版本:

    // code seen by outside users, enforces constraint
    function externalFunction<K extends string, R extends K>(
      someInterface: SomeInterface<K, R>
    ) {
        internalFunction(someInterface)
    }
    
    // code not exposed outside, widens to non-generic version
    type SomeWiderInterface = SomeInterface<string, string>
    const someWiderValue: SomeWiderInterface = value; // accepted
    function internalFunction(someWiderInterface: SomeWiderInterface) {
        // do stuff
    }
    

    Playground link to code

    【讨论】:

      猜你喜欢
      • 2021-12-08
      • 2020-02-06
      • 2020-01-07
      • 1970-01-01
      • 2019-07-03
      • 2019-04-16
      • 2019-02-13
      • 2022-12-05
      • 1970-01-01
      相关资源
      最近更新 更多