Filip
Filip

Reputation: 945

TypeScript Type 'Record<string, string>' is not assignable to type 'string'

Why is this wrong? I've had similar issues with this and never figured it out. Whenever I do this:

    type dataType = {
        [key: string]: string | Record<string, string>;
    };

    const rawData = [
        {
            name: 'XXXX',
            commission: 'XXXX',
            psc: 'XXX XX',
            ico: 'XXXXXXXX',
            address: 'XXXXXXX',
            city: 'XXXXXXXXXXX',
        },
    ];
    const createData = ({ name, commission, ico, address, psc, city }: dataType) => {
        return { name, commission, legal: { name, ico, address, city: `${psc} ${city}` } };
    };

    const rows: dataType[] = [createData(rawData[0])];

This should theoretically be working fine, should it not? The dataType is a type of an object with any key that is string with a value of either string or another object. Why does this not work?

Upvotes: 1

Views: 23681

Answers (2)

Zotille
Zotille

Reputation: 123

Sample usage

Cause name can be string | Record<string,string>, so the legal.name in the return type could be string | Record<string,string> which means the type of legal should be Record<string, string | Record<string,string>>;

However, you defined return type of createData is dataType, that means type of legal can't cover the real type you return. Your define lead th cycle, try write another return type for your function.

Personally, I don't recommend you write type that way.

type DataType = {
  name: string,
  commission: string,
  psc: string,
  ico: string,
  address: string,
  city: string,
};

type AnotherDataType = {
  name: string,
  commission: string,
  legal: Partial<DataType>
}

might be better.

Upvotes: 2

Bergi
Bergi

Reputation: 664385

Your createData should not take a dataType object as its argument. The way you wrote it, name, ico and address might be of type Record<string, string>, arriving at the signature

const createData: ({ name, commission, ico, address, psc, city }: dataType) => {
    name: string | Record<string, string>;
    commission: string | Record<string, string>;
    legal: {
        name: string | Record<string, string>;
        ico: string | Record<...>;
        address: string | Record<...>;
        city: string;
    };
}

These records inside the legal object are invalid when you try to assign the result to a dataType variable.

Instead, use

const createData = ({ name, commission, ico, address, psc, city }: Record<string, string>) => …

which is the proper type fitting your rawData. (You might want to be more precise and define an interface with the exact properties).

Upvotes: 4

Related Questions