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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/36311284/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 07:02:23  来源:igfitidea点击:

Is there a way to "extract" the type of TypeScript interface property?

typescripttypingdefinitelytyped

提问by Kuba Jagoda

Let's suppose there's a typing file for library X which includes some interfaces.

让我们假设库 X 有一个包含一些接口的类型文件。

interface I1 {
    x: any;
}

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

In order to work with this library I need pass around an object that is of exactly the same type as I2.y. I can of course create identical interface in my source files:

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

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

let myVar: MyInterface;

but then I get the burden of keeping it up to date with the one from library, moreover it can be very large and result in lot of code duplication.

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

Therefore, is there any way to "extract" the type of this specific property of the interface? Something similar to let myVar: typeof I2.y(which doesn't work and results in "Cannot find name I2" error). Thanks in advance.

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



Edit: after playing a bit in TS Playground I noticed that following code achieves exactly what I want to:

编辑:在 TS Playground 玩了一会儿后,我注意到下面的代码实现了我想要的:

declare var x: I2;
let y: typeof x.y;

However it requires a redundant variable xto be declared. I am looking for a way to achieve this without that declaration.

但是,它需要x声明一个冗余变量。我正在寻找一种无需该声明即可实现这一目标的方法。

回答by Micha? Miszczyszyn

It wasn't possible before but luckily it is now, since TypeScript version 2.1. It has been released on the 7th of December 2016 and it introduces indexed access typesalso called lookup types.

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

The syntax looks exactly like element access but written in place of types. So in your case:

语法看起来与元素访问完全一样,但用类型代替。所以在你的情况下:

interface I1 {
    x: any;
}

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

let myVar: I2['y'];  // indexed access type

Now myVarhas type of I2.y.

现在myVarI2.y.

Check it out in TypeScript Playground.

TypeScript Playground 中查看。

回答by JCorriveau

An interface is like the definition of an object. Then y is a property of your I2 object, that is of a certain type, in that case "anonymous".

接口就像对象的定义。然后 y 是您的 I2 对象的属性,即某种类型,在这种情况下是“匿名的”。

You could use another interface to define y and then use it as your y type like this

您可以使用另一个接口来定义 y,然后将其用作您的 y 类型,如下所示

interface ytype {
   a: I1;
   b: I1;
   c: I1;
}

interface I2 {
    y: ytype;
    z: any;
}

You can put your interface in a file and use extract so you can import it in other files of your projects

您可以将您的界面放在一个文件中并使用提取,以便您可以将其导入到项目的其他文件中

export interface ytype {
   a: I1;
   b: I1;
   c: I1;
}



 export interface I2 {
        y: ytype;
        z: any;
    }

You can import it that way :

你可以这样导入:

   import {I1, I2, ytype} from 'your_file'