我在TypeScript中有以下接口:

interface IX {
    a: string,
    b: any,
    c: AnotherType
}

我声明了一个该类型的变量并初始化了所有属性

let x: IX = {
    a: 'abc',
    b: null,
    c: null
}

然后在稍后的init函数中为它们赋值

x.a = 'xyz'
x.b = 123
x.c = new AnotherType()

但我不喜欢在声明对象时为每个属性指定一堆默认空值,因为它们稍后将被设置为实值。我能告诉接口默认属性我不提供为空吗?是什么让我这样做:

let x: IX = {
    a: 'abc'
}

而不会产生编译器错误。现在它告诉我了

TS2322:类型“{}”不能赋值给类型 “九”。属性“b”在类型“{}”中缺失。


当前回答

在有很多参数的情况下,最好让用户只插入几个参数,而且没有特定的顺序。

例如,不好的做法:

foo(a?, b=1, c=99, d=88, e?)
foo(null, null, null, 3)

因为你必须在你真正想要的参数(d)之前提供所有参数。

好的做法是:

foo({d=3})

实现它的方法是通过接口。 你需要将参数定义为一个接口,像这样:

interface Arguments {
    a?;
    b?; 
    c?;
    d?;
    e?;
}

并像这样定义函数:

foo(arguments: Arguments)

现在接口变量不能得到默认值,那么我们如何定义默认值呢?

简单,我们为整个接口定义默认值:

foo({
        a,
        b=1,
        c=99,
        d=88,
        e                    
    }: Arguments)

现在如果用户通过:

foo({d=3})

实际参数为:

{
    a,
    b=1,
    c=99,
    d=3,
    e                    
}

另一个不声明接口的选项是:

foo({
        a=undefined,
        b=1,
        c=99,
        d=88,
        e=undefined                    
    })

跟进: 在前面的函数定义中,我们为参数对象的字段定义了默认值,但没有为对象本身定义默认值。 因此,我们将从下面的调用中得到一个提取错误(例如不能读取未定义的属性'b'):

foo()

有两种可能的解决方案:

1.

const defaultObject = {a=undefined, b=1, c=99, d=88, e=undefined}
function foo({a=defaultObject.a, b=defaultObject.b, c=defaultObject.c, d=defaultObject.d, e=defaultObject.e} = defaultObject)
function foo(object = {}) {
    object = { b=1, c=99, d=88, ...object }
    //Continue the function code..
}

跟进: 如果你需要类型和默认值(并且你不想声明一个接口),你可以这样写:

function foo(params: {a?: string, b?: number, c?: number, d?: number, e?: string}) {
    params = { b:1, c:99, d:88, ...params }
    //Continue the function code..
}

其他回答

我的解决方案:

我在对象上创建了包装器。指派以修复键入问题。

export function assign<T>(...args: T[] | Partial<T>[]): T {
  return Object.assign.apply(Object, [{}, ...args]);
}

用法:

env.base.ts

export interface EnvironmentValues {
export interface EnvironmentValues {
  isBrowser: boolean;
  apiURL: string;
}

export const enviromentBaseValues: Partial<EnvironmentValues> = {
  isBrowser: typeof window !== 'undefined',
};

export default enviromentBaseValues;

env.dev.ts

import { EnvironmentValues, enviromentBaseValues } from './env.base';
import { assign } from '../utilities';

export const enviromentDevValues: EnvironmentValues = assign<EnvironmentValues>(
  {
    apiURL: '/api',
  },
  enviromentBaseValues
);

export default enviromentDevValues;

接口的默认值是不可能的,因为接口只存在于编译时。

可选择的解决方案:

例子:

class AnotherType {}

interface IX {
    a: string,
    b: any,
    c: AnotherType | null
}

function makeIX (): IX {
    return {
    a: 'abc',
    b: null,
    c: null
    }
}

const x = makeIX();

x.a = 'xyz';
x.b = 123;
x.c = new AnotherType();

关于你的例子,我唯一改变的是使属性c both AnotherType |为空。这将是必要的,没有任何编译器错误(这个错误也出现在你的例子中,你初始化为null属性c)。

我需要这个React组件。

你可以使用Nullish Coalescing Operator,它会在左手值为Null或Undefined时赋一个默认值:

interface IX {
    a: string,
    b?: any,
    c?: AnotherType
}

const ixFunction: React.FC<IX> = (props) => {
  console.log(props.b?? "DefaultValue")
}

但这只适用于只在一个地方使用变量的情况。

我们正在努力解决这个问题。使用类而不是接口。

class IX {
  a: String = '';
  b?: any;
  c: Cee = new Cee();
}

class Cee {
  c: String = 'c';
  e: String = 'e';
}

在有很多参数的情况下,最好让用户只插入几个参数,而且没有特定的顺序。

例如,不好的做法:

foo(a?, b=1, c=99, d=88, e?)
foo(null, null, null, 3)

因为你必须在你真正想要的参数(d)之前提供所有参数。

好的做法是:

foo({d=3})

实现它的方法是通过接口。 你需要将参数定义为一个接口,像这样:

interface Arguments {
    a?;
    b?; 
    c?;
    d?;
    e?;
}

并像这样定义函数:

foo(arguments: Arguments)

现在接口变量不能得到默认值,那么我们如何定义默认值呢?

简单,我们为整个接口定义默认值:

foo({
        a,
        b=1,
        c=99,
        d=88,
        e                    
    }: Arguments)

现在如果用户通过:

foo({d=3})

实际参数为:

{
    a,
    b=1,
    c=99,
    d=3,
    e                    
}

另一个不声明接口的选项是:

foo({
        a=undefined,
        b=1,
        c=99,
        d=88,
        e=undefined                    
    })

跟进: 在前面的函数定义中,我们为参数对象的字段定义了默认值,但没有为对象本身定义默认值。 因此,我们将从下面的调用中得到一个提取错误(例如不能读取未定义的属性'b'):

foo()

有两种可能的解决方案:

1.

const defaultObject = {a=undefined, b=1, c=99, d=88, e=undefined}
function foo({a=defaultObject.a, b=defaultObject.b, c=defaultObject.c, d=defaultObject.d, e=defaultObject.e} = defaultObject)
function foo(object = {}) {
    object = { b=1, c=99, d=88, ...object }
    //Continue the function code..
}

跟进: 如果你需要类型和默认值(并且你不想声明一个接口),你可以这样写:

function foo(params: {a?: string, b?: number, c?: number, d?: number, e?: string}) {
    params = { b:1, c:99, d:88, ...params }
    //Continue the function code..
}