2

With typescript, I want to define a type T which can check if the value is a substring with the given strings. It's like

const a = 'apple'
const b = 'banana'
const c = 'cat'
const d = 'dog'
type T1<typeof T, typeof U> = ?
const t1:T<a,b> = 'xyz apple banana' // pass
const t2:T<b,c> = 'banana cat abc' // pass
const t3:T<a,b> = 'abc xyz def' // error, as not contain 'apple' and 'banana'

How can I define that type?

1 Answer 1

4

If you wanted to check just one string value, that would be pretty simple.

type ContainsOneString<T extends string> = `${string}${T}${string}`

const tOneA: ContainsOneString<'cat'> = "i pet a cat" // pass
const tOneB: ContainsOneString<'cat'> = "i pet a dog" // error

This is a template literal type where the ${string}'s act like wild cards, and ${T} is the required substring that must be preset.

Playground


Extending that to two strings is trickier, mainly because you don't know the order.

To get around that you can use a union type, where T before U is one member, and U before T is the other member:

type TwoStrings<T extends string, U extends string> =
  `${string}${T}${string}${U}${string}`

type ContainsTwoStrings<T extends string, U extends string> =
  TwoStrings<T, U> | TwoStrings<U, T>

const t1: ContainsTwoStrings<'apple', 'banana'> = 'xyz apple banana' // pass
const t2: ContainsTwoStrings<'banana', 'cat'> = 'banana cat abc' // pass
const t3: ContainsTwoStrings<'apple', 'banana'> = 'abc xyz def' // error, as not contain 'apple' and 'banana'

Here TwoStrings is a helper type that defines a string where one substring is first, and the other is second. Then ContainsTwoStrings is a union of the T then U case, and the U then T case.

Playground

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.