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

让我们假设有一个库X的输入文件,其中包含一些接口。

interface I1 {
x: any;
}
    

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

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

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


let myVar: MyInterface;

但是然后我就有了从库中更新它的负担,而且它可能非常大,导致大量的代码重复。

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


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

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

然而,它需要声明一个多余的变量x。我正在寻找一种方法来实现这一目标,而不需要声明。

127930 次浏览

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

你可以使用另一个接口来定义y,然后像这样使用它作为y类型

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


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

您可以将接口放在文件中并使用extract,以便将其导入项目的其他文件中

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






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

你可以这样导入:

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

这在以前是不可能的,但幸运的是,现在是,因为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

现在myVar的类型为I2.y

打印稿操场中查看。

要扩展已接受的答案,还可以使用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 };

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

interface Colors {
white: "#fff"
black: "#000"
}


type ColorValues = Colors[keyof Colors]
// ColorValues = "#fff" | "#000"

这只是一个从联合对象类型中提取文字类型的例子:

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


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