То, что вам нужно, - это возможность расширять нужный тип по подтипам. Это может быть достигнуто введением обобщенных параметров c:
type FunctionWithParamWithTrace<Args extends {
trace: string;
[index: string]: any
}> = (args: Args) => any;
const doSomethingAndTrace: FunctionWithParamWithTrace<{ trace: string }>
= (args) => {}; // looks good
const doSomethingElseAndTrace: FunctionWithParamWithTrace<{ trace: string, foo: 'bar' }>
= (args) => {} // works
Причина, по которой вы не можете использовать более строгий тип в качестве аргумента, видна в следующем коде:
type FunctionWithParamWithTrace = (args: {
trace: string;
[index: string]: any
}) => any;
type FunctionWithMoreStrictParameters = (args: { trace: string, foo: string }) => any
type NoItDoesNotExtends
= FunctionWithMoreStrictParameters extends FunctionWithParamWithTrace
? true
: false // false
Это означает, что ваша более строгая функция не является подмножеством исходной, поэтому ее нельзя использовать как таковую. Это почему? Представьте, что у вас есть функция, которая работает с более точными аргументами, например, функция, которая всегда получает foo
, эта функция не может быть использована вместо функции, которая может принимать любой объект. Вот почему это не может быть выполнено.
Ниже приведен другой пример, который, возможно, расскажет, почему использование более строгой аргументированной функции не является хорошей идеей, а блоки TS такие:
function f(arg: {a: string, b: string | number}) {
return arg.b.concat('b cannot be used as string as it can be number') // error
}
function g(arg: {a: string, b: string}) {
return arg.b.concat(' b can be used as string') // pass compilation
}
Функция g
тип аргумента является подмножеством функции f
тип аргумента, поэтому можно использовать вместо f
? Скорее наоборот, вместо g
можно использовать функцию f
, поскольку она может работать с более широким шрифтом и означает, что ее тело должно выполнять дополнительные проверки. Это видно в функции f
, мы не можем просто использовать string | number
как string
, нам нужно выполнить дополнительные проверки значения. Но когда мы смотрим на g
, ему не нужно делать проверки, поскольку он работает только с string
. Что бы тогда произошло, если бы мы использовали g
вместо f
и получили бы аргумент number
, это, конечно, время выполнения cra sh.
В итоге тип функции - это подмножество другой тип функции, если он более гибкий в типах аргументов, не более строгий.