打字稿接口:并非所有类型为“string |的成分” (() => string)' 是可调用的。“字符串”类型没有调用签名

Ami*_*gar 7 javascript-objects typescript

interface ExampleType {
  [key: string]: string | (() => string);
}

const testObj: ExampleType = {
  firstName: "Peter",
  lastName: "Parker",
  gender: "male",
  getFullName: () => "I am Peter Parker",
};

const { firstName, lastName, getFullName } = testObj;


console.log(getFullName()); // this does  not works

if (typeof getFullName === "function") {
    console.log(getFullName()) // this works
}
Run Code Online (Sandbox Code Playgroud)

我收到以下错误:**此表达式不可调用。并非所有类型为 'string | 的成分| (() => string)' 是可调用的。'string' 类型没有调用签名。**

Kar*_*ski 6

By saying testObj: ExampleType, you are saying that testObj will be an object in which the properties are either string or () => string. That's a broad, weak promise. However, you know exactly which properties will be of which kind.

Solution one

Tell the compiler everything you know. Include concrete property names in ExampleType.

interface ExampleType {
  firstName: string;
  lastName: string;
  gender: string;
  getFullName: () => string;
}

const testObj: ExampleType = {
  firstName: "Peter",
  lastName: "Parker",
  gender: "male",
  getFullName: () => "I am Peter Parker",
};

const { firstName, lastName, getFullName } = testObj;

console.log(getFullName()); // this works
Run Code Online (Sandbox Code Playgroud)

Solution two

If you want to use ExampleType as a blueprint, but want the specific properties inferred for you, use a helper function like specific defined below.

interface ExampleType {
  [key: string]: string | (() => string);
}

const specific = <T>() => <U extends T>(argument: U) => argument;

const testObj = specific<ExampleType>()({
  firstName: "Peter",
  lastName: "Parker",
  gender: "male",
  getFullName: () => "I am Peter Parker",
});

const { firstName, lastName, getFullName } = testObj;

console.log(getFullName()); // this works
Run Code Online (Sandbox Code Playgroud)