是否有方法更改*.d中定义的接口属性的类型?Ts在typescript中?

例如: x.d.ts中的接口定义为

interface A {
  property: number;
}

我想在我写入的typescript文件中改变它

interface A {
  property: Object;
}

甚至这个也可以

interface B extends A {
  property: Object;
}

这种方法有效吗?当我试我的系统时,它不工作。只是想确认一下有没有可能?


当前回答

有趣的是,我花了一天的时间调查解决同一个案子的可能性。 我发现这样做是不可能的:

// a.ts - module
export interface A {
    x: string | any;
}

// b.ts - module
import {A} from './a';

type SomeOtherType = {
  coolStuff: number
}

interface B extends A {
    x: SomeOtherType;
}

产生原因模块可能不知道应用程序中所有可用的类型。从各个地方移植所有东西,编写这样的代码是很无聊的。

export interface A {
    x: A | B | C | D ... Million Types Later
}

您必须稍后定义类型,以使自动完成工作良好。


所以你可以欺骗一下:

// a.ts - module
export interface A {
    x: string;
}

默认保留some类型,当不需要重写时,允许自动完成工作。

Then

// b.ts - module
import {A} from './a';

type SomeOtherType = {
  coolStuff: number
}

// @ts-ignore
interface B extends A {
    x: SomeOtherType;
}

在这里使用@ts-ignore标志禁用愚蠢的异常,告诉我们我们做错了什么。有趣的是,一切都按照预期进行。

在我的情况下,我减少了类型x的范围,它允许我做更严格的代码。例如,你有一个100个属性的列表,你把它减少到10个,以避免愚蠢的情况

其他回答

更好的解决方案是使用以下修改类型(双关语)的这个答案

export type Modify<T, R extends Partial<T>> = Omit<T, keyof R> & R;

这也将检查你覆盖的键是否也存在于原始接口中,从而确保如果原始接口更改了名称,那么你将得到编译时错误,你也必须更改名称。

解释:

举个例子。

interface OriginalInterface {
    id: string
}

修改后的型号如下图所示

interface ModifiedInterface {
    id: number
}

现在,假设在未来,OriginalInterface的id被重命名为uId,然后使用我的类型实用程序,你将得到如下错误

interface ModifiedInterface {
    id: number // Type '{ geo_point1: GeoPoint | null; }' has no properties in common with type 'Partial<Address>'.ts(2559)
}

日期:19/3/2021。 我认为最新的typescript(4.1.2)版本支持d.ts文件中的接口覆盖。

// in test.d.ts

interface A {
  a: string
}

export interface B extends A {
  a: number
}

// in any ts file
import { B } from 'test.d.ts'

// this will work
const test: B = { a: 3 }

// this will not work
const test1: B = { a: "3" }

如果你只想修改一个现有属性的类型,而不是删除它,那么&就足够了:

// Style that accepts both number and percent(string)
type BoxStyle = {
  height?: string | number,
  width?: string | number,
  padding?: string | number,
  borderRadius?: string | number,
}

// These are both valid
const box1: BoxStyle = {height: '20%', width: '20%', padding: 0, borderRadius: 5}
const box2: BoxStyle = {height: 85, width: 85, padding: 0, borderRadius: 5}

// Override height and width to be only numbers
type BoxStyleNumeric = BoxStyle & {
  height?: number,
  width?: number,
}

// This is still valid
const box3: BoxStyleNumeric = {height: 85, width: 85, padding: 0, borderRadius: 5}

// This is not valid anymore
const box4: BoxStyleNumeric = {height: '20%', width: '20%', padding: 0, borderRadius: 5}
 type ModifiedType = Modify<OriginalType, {
  a: number;
  b: number;
}>
 
interface ModifiedInterface extends Modify<OriginalType, {
  a: number;
  b: number;
}> {}

受到ZSkycat扩展的省略解决方案的启发,我想出了这个:

type Modify<T, R> =省略<T, R> & R键; //在typescript@3.5之前 type修改<T, R> =选择<T,排除<keyof T, keyof R>> & R

例子:

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

type ModifiedType  = Modify<OriginalInterface , {
  a: number;
  b: number;
}>

// ModifiedType = { a: number; b: number; c: number; }

一步一步地:

type R0 = Omit<OriginalType, 'a' | 'b'>        // { c: number; }
type R1 = R0 & {a: number, b: number }         // { a: number; b: number; c: number; }

type T0 = Exclude<'a' | 'b' | 'c' , 'a' | 'b'> // 'c'
type T1 = Pick<OriginalType, T0>               // { c: number; }
type T2 = T1 & {a: number, b: number }         // { a: number; b: number; c: number; }

TypeScript实用工具类型


深度修改v3

interface Original {
  a: {
    a: string
    b: { a: string }
    c: string
    d: string         // <- keep this one 
  }
}

interface Overrides {
  a: {
    a: { a: number }  // <- overwrite string with object
    b: number         // <- overwrite object with number
    c: number         // <- overwrite string with number
    e: number         // <- new property
  }
}

type ModifiedType = ModifyDeep<Original, Overrides>
interface ModifiedInterface extends ModifyDeep<Original, Overrides> {}
const example: ModifiedType = {
  a: {
    a: { a: number },
    b: number,
    c: number,
    d: string,
    e: number,
  }
}

在下面找到ModifyDeep。

对于像我这样的懒人来说,简单的答案是:

type Overrided = Omit<YourInterface, 'overrideField'> & { overrideField: <type> }; 
interface Overrided extends Omit<YourInterface, 'overrideField'> {
  overrideField: <type>
}