有没有办法"提取"TypeScript接口属性的类型?

Kub*_*oda 53 typing typescript definitelytyped

假设库X的打包文件包含一些接口.

interface I1 {
    x: any;
}

interface I2 {
    y: {
        a: I1,
        b: I1,
        c: I1
    }
    z: any
}
Run Code Online (Sandbox Code Playgroud)

为了使用这个库,我需要传递一个与其完全相同的对象I2.y.我当然可以在源文件中创建相同的界面:

interface MyInterface {
    a: I1,
    b: I1,
    c: I1
}

let myVar: MyInterface;
Run Code Online (Sandbox Code Playgroud)

但是后来我承担了使用库中的那个保持最新的负担,而且它可能非常大并导致大量代码重复.

因此,有没有办法"提取"接口的这个特定属性的类型?类似的东西let myVar: typeof I2.y(不起作用,导致"找不到名字I2"错误).提前致谢.


编辑:在TS Playground中玩了一下后,我注意到以下代码完全符合我的要求:

declare var x: I2;
let y: typeof x.y;
Run Code Online (Sandbox Code Playgroud)

但是,它需要x声明一个冗余变量.我正在寻找一种方法来实现这个没有这个声明.

Mic*_*zyn 110

以前不可能,但幸运的是现在,因为TypeScript版本2.1.它已于2016年12月7日发布,它引入了索引访问类型,也称为查找类型.

语法看起来与元素访问完全相同,但是代替类型编写.所以在你的情况下:

interface I1 {
    x: any;
}

interface I2 {
    y: {
        a: I1,
        b: I1,
        c: I1
    }
    z: any
}

let myVar: I2['y'];  // indexed access type
Run Code Online (Sandbox Code Playgroud)

现在myVar有类型的I2.y.

TypeScript Playground中查看它.

  • 假设我们正在循环使用“I2”作为类型定义的对象的键。循环时如何动态获取特定键的类型。这; `let z: typeof x[a];` 不起作用,其中 `a` 是字符串形式的某个键。它告诉我“a”指的是一个值并且必须指的是一个类型。我该怎么做呢?有可能以任何方式吗?谢谢! (5认同)
  • 如果“y”是数组,有什么方法可以提取元素的类型吗?例如 I2{ y: {..}[]} (4认同)
  • @JohnB 是的,您可以以相同的方式访问它,即。`I2['y'][0]` 见:http://www.typescriptlang.org/play/index.html#src=interface%20I1%20%7B%0D%0A%20%20%20%20x %3A%20any%3B%0D%0A%7D%0D%0A%0D%0Ainterface%20I2%20%7B%0D%0A%20%20%20%20y%3A%20Array%3CI1%3E%0D%0A %20%20%20%20z%3A%20any%0D%0A%7D%0D%0A%0D%0Alet%20myVar%3A%20I2%5B'y'%5D%5B0%5D%3B%0D%0A% 0D%0Aconsole.log(myVar.x)%3B%0D%0A (3认同)
  • 这真是厉害的能力 (3认同)
  • @JohnB 是的,您可以以完全相同的方式执行此操作,因为数组索引就像对象属性一样。在这里查看:http://www.typescriptlang.org/play/#src=let%20x%3A%20Array%3Cnumber%3E%20%3D%20%5B%5D%3B%0D%0Alet%20y% 3A%20typeof%20x%5B0%5D%3B%20%2F%2Fy%20is%20of%20type%20%22number%22%0D%0A%0D%0A%2F%2Fworks%20also%20with%20tuples%0D% 0Alet%20x1%3A%20%5Bstring%2C%20boolean%2C%20number%5D%3B%0D%0Alet%20y1%3A%20typeof%20x1%5B1%5D%3B%20%2F%2Fy1%20is%20of% 20类型%20布尔值 (2认同)

Jam*_*ond 22

只是从联合对象类型中提取文字类型的示例:

type Config = {
    key: "start_time",
    value: number,
} | {
    key: "currency",
    value: string,
}

export type ConfigKey = Config["key"];
// "start_time"|"currency"

Run Code Online (Sandbox Code Playgroud)


Gab*_*son 19

keyof Colors将返回所有键的列表"white" | "black"。当此键列表传递到 Colors 接口时,类型将是给定键的所有值"#fff" |\xc2\xa0#000

\n
interface Colors {\n  white: "#fff"\n  black: "#000"\n}\n\ntype ColorValues = Colors[keyof Colors]\n// ColorValues = "#fff" | "#000"\n
Run Code Online (Sandbox Code Playgroud)\n


Ben*_*ing 8

要扩展已接受的答案,您还可以使用type关键字分配类型并在其他地方使用它。

// Some obscure library
interface A {
  prop: {
    name: string;
    age: number;
  }
}

// Your helper type
type A_Prop = A['prop']

// Usage
const myThing: A_prop = { name: 'June', age: 29 };
Run Code Online (Sandbox Code Playgroud)