Reputation: 65
I have this function:
const plainText = (text: string) => ({
type: 'plain_text',
text,
emoji: true,
});
At the moment the inferred type return is:
const plainText: (text: string) => {
type: string;
text: string;
emoji: boolean;
}
Is there a way to make it return like this with the type of type
being 'plain_text'
as opposed to string
? Or do I need to manually declare the return type?
const plainText: (text: string) => {
type: 'plain_text';
text: string;
emoji: boolean;
}
I found I can do the following, but is this the best way to do it?
const plainText = (text: string) => ({
type: 'plain_text' as 'plain_text',
text,
emoji: true,
});
I've got others like this:
const text = (text: string) => ({
type: 'section',
text: {
type: 'mrkdwn',
text,
},
});
I'm trying to just create a bunch of functions to represent some repeated basic Slack Block types that I'm using so I can just pass them with eg. plainText('hello')
. As I won't need to configure them, everything remains static and only the text changes.
The problem is when I call it against a Slack Client it required the typing to be exactly type: 'plain_text'
instead of type: 'string'
. Type definition
Upvotes: 2
Views: 518
Reputation: 42188
The problem is when I call it against a Slack Client it required the typing to be exactly type: 'plain_text' instead of type: 'string'. Type definition
You can declare a specific return type for your function rather than letting it be inferred. My recommendation is that you make use of the types which are already defined by Slack when you are making factories for them.
import {PlainTextElement} from "@slack/types";
const plainText = (text: string): PlainTextElement => ({
type: 'plain_text',
text,
emoji: true,
});
Upvotes: 2
Reputation: 2539
If you just want the type
property to be the string literal, then you can use as const
on that property to force typescript to treat it as the literal string "plain_text" rather than a generic string
type:
const plainText = (text: string) => ({
type: 'plain_text' as const,
text,
emoji: true,
});
What you did with 'plain_text' as 'plain_text'
is also fine though! They are equivalent.
Upvotes: 2
Reputation: 33051
Just use generics:
const plainText = <T extends string>(text: T) => ({
type: 'plain_text',
text,
emoji: true,
}) as const; // small update
const foo = plainText('hello')
In above case, TS will try to infer the type of argument.
Upvotes: 0