8

In terms of deprecation strategies, we can mark a value as deprecated and this can imply that 'this thing exists now and should work, but in future major releases this thing may disappear and will break your code'.

eg:

type MyClient =  {
/** 
  @deprecated - prefer using `bar` instead 
*/
foo: () => string; 
bar: () => Promise<string>; 

}

At the same time, in terms of an extensible/non-breaking strategy - we can always allow additional optional inputs to add extra functionality without breaking existing code:


type MyClient =  {
/** 
  @deprecated - prefer using `bar` instead 
*/
foo: () => string; 
  • bar: () => Promise<string>;
  • bar: (options?: {x: boolean}) => Promise<string>;

}

In this scenario, I want to indicate that that options object will be mandatory in future major releases - is there a term for this kind of annotation?

dwjohnston
  • 2,725

2 Answers2

9

That's still a deprecation. You will be deprecating the optional nature of the parameter, which will be a breaking change.

For the purpose of your consumer being alerted to the deprecation, it's irrelevant whether you're going to be removing bar entirely or changing bar in a way that old usages will break.

It's a deprecation, and it should be treated as a deprecation, because that's what it is: a currently valid way of working today will break in a future version.

It is of course relevant to also document what the new way of working is/will be; but whether that's a totally different way of working or a similarly named method with a slightly different signature is an irrelevant distinction. We don't spend time quantifying the degree to which it is a breaking change. Either it's a breaking change or it's not. "A bit of a breaking change" is not a thing.

Flater
  • 58,824
2

As @jonrsharpe points out in the comments, this is simply overloading a function and deprecating one of the overloads.

In TypeScript you would do it this way:


async function bar(options: {x : boolean}) : Promise<string>; 
/**
 * @deprecated - options object will be mandatory
 */
async function bar() : Promise<string>; 
async function bar(options?: {x: boolean}) : Promise<string> {
    return ""; 
}

type MyClient = { bar: typeof bar, }

async function main(client: MyClient) {

const result1 : string = await client.bar(); 
const result2 : string = await client.bar({x: true}); 

}

(Straight declaration of a union of function signatures doesn't play nicely in TypeScript - see: https://stackoverflow.com/questions/43662729/union-type-of-two-functions-in-typescript)

Note the IDE deprecation strikethrough hint:

enter image description here

dwjohnston
  • 2,725